diff --git a/.clang-tidy b/.clang-tidy index 134cb61e561..5342022d5d2 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -67,7 +67,7 @@ Checks: '-*,clang-diagnostic-*,clang-analyzer-*,-misc-unused-parameters, google-upgrade-googletest-case, modernize-avoid-bind, - modernize-concat-nested-namespaces, + -modernize-concat-nested-namespaces, modernize-deprecated-headers, modernize-deprecated-ios-base-aliases, modernize-loop-convert, diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index d02a39a7b08..f5e7f5f3f19 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -54,7 +54,7 @@ jobs: endpoint: ${{ secrets.OSS_ENDPOINT }} bucket: nebula-graph asset-path: pkg-build/cpack_output - target-path: package/v2-nightly/${{ steps.vars.outputs.subdir }} + target-path: package/nightly/${{ steps.vars.outputs.subdir }} docker: name: build docker image diff --git a/.github/workflows/rc.yml b/.github/workflows/rc.yml new file mode 100644 index 00000000000..80da0b19ae5 --- /dev/null +++ b/.github/workflows/rc.yml @@ -0,0 +1,109 @@ +name: rc + +on: + push: + branches: + - 'v[0-9]+.*' + +concurrency: + group: rc + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + package: + name: build package + runs-on: [self-hosted, nebula] + strategy: + fail-fast: false + matrix: + os: + - ubuntu1604 + - ubuntu1804 + - ubuntu2004 + - centos7 + - centos8 + container: + image: vesoft/nebula-dev:${{ matrix.os }} + env: + BUILD_DIR: ./pkg-build + CPACK_DIR: ./pkg-build/cpack_output + SYMS_DIR: ./pkg-build/symbols + steps: + - uses: webiny/action-post-run@2.0.1 + with: + run: sh -c "find . -mindepth 1 -delete" + - uses: actions/checkout@v2 + - uses: ./.github/actions/tagname-action + id: tag + - name: package + run: ./package/package.sh -b ${{ steps.tag.outputs.tag }} -t RelWithDebInfo -r OFF -p ON -s TRUE + - name: output some vars + run: | + tar zcf ${{ env.CPACK_DIR }}/nebula-${{ steps.tag.outputs.tagnum }}.tar.gz --exclude=${{ env.BUILD_DIR }} ./* + find ${{ env.CPACK_DIR }} -type f \( -iname \*.deb -o -iname \*.rpm -o -iname \*.tar.gz \) -exec bash -c "sha256sum {} > {}.sha256sum.txt" \; + - uses: ./.github/actions/upload-to-oss-action + with: + key-id: ${{ secrets.OSS_ID }} + key-secret: ${{ secrets.OSS_SECRET }} + endpoint: ${{ secrets.OSS_ENDPOINT }} + bucket: nebula-graph + asset-path: ${{ env.CPACK_DIR }} + target-path: rc/${{ steps.tag.outputs.tagnum }} + - uses: ./.github/actions/upload-to-oss-action + with: + key-id: ${{ secrets.OSS_ID }} + key-secret: ${{ secrets.OSS_SECRET }} + endpoint: ${{ secrets.OSS_ENDPOINT }} + bucket: nebula-graph + asset-path: ${{ env.SYMS_DIR }} + target-path: rc/${{ steps.tag.outputs.tagnum }}/symbols + + docker_build: + name: docker-build + runs-on: [self-hosted, nebula] + strategy: + fail-fast: false + matrix: + service: + - graphd + - metad + - storaged + - tools + steps: + - uses: webiny/action-post-run@2.0.1 + with: + run: sh -c "find . -mindepth 1 -delete" + - uses: actions/checkout@v2 + - uses: ./.github/actions/tagname-action + id: tagname + - id: docker + run: | + majorver=$(git tag -l --sort=v:refname | tail -n1 | cut -f1 -d'.') + tag="" + if [[ $majorver == ${{ steps.tagname.outputs.majorver }} ]]; then + tag="${{ secrets.HARBOR_REGISTRY }}/vesoft/nebula-${{ matrix.service }}:latest" + fi + echo "::set-output name=tag::$tag" + - uses: docker/setup-qemu-action@v1 + - uses: docker/setup-buildx-action@v1 + - uses: docker/login-action@v1 + with: + registry: ${{ secrets.HARBOR_REGISTRY }} + username: ${{ secrets.HARBOR_USERNAME }} + password: ${{ secrets.HARBOR_PASSWORD }} + - uses: docker/build-push-action@v2 + with: + context: . + file: ./docker/Dockerfile.${{ matrix.service }} + platforms: linux/amd64,linux/arm64 + tags: | + ${{ secrets.HARBOR_REGISTRY }}/vesoft/nebula-${{ matrix.service }}:${{ steps.tagname.outputs.tag }} + ${{ secrets.HARBOR_REGISTRY }}/vesoft/nebula-${{ matrix.service }}:${{ steps.tagname.outputs.majorver }} + ${{ steps.docker.outputs.tag }} + push: true + build-args: | + BRANCH=${{ steps.tagname.outputs.tag }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e9e0893cc0..8cf7db89b47 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,54 +15,21 @@ defaults: jobs: package: - name: build package - runs-on: [self-hosted, nebula] - strategy: - fail-fast: false - matrix: - os: - - ubuntu1604 - - ubuntu1804 - - ubuntu2004 - - centos7 - - centos8 + name: package + runs-on: ubuntu-latest container: - image: vesoft/nebula-dev:${{ matrix.os }} - env: - BUILD_DIR: ./pkg-build - CPACK_DIR: ./pkg-build/cpack_output - SYMS_DIR: ./pkg-build/symbols + image: vesoft/nebula-dev:centos7 steps: - - uses: webiny/action-post-run@2.0.1 - with: - run: sh -c "find . -mindepth 1 -delete" - uses: actions/checkout@v2 - - name: Check License Header - uses: apache/skywalking-eyes@main - uses: ./.github/actions/tagname-action id: tag - - name: package - run: ./package/package.sh -b ${{ steps.tag.outputs.tag }} -t RelWithDebInfo -r OFF -p ON -s TRUE - - name: output some vars - run: | - tar zcf ${{ env.CPACK_DIR }}/nebula-${{ steps.tag.outputs.tagnum }}.tar.gz --exclude=${{ env.BUILD_DIR }} ./* - find ${{ env.CPACK_DIR }} -type f \( -iname \*.deb -o -iname \*.rpm -o -iname \*.tar.gz \) -exec bash -c "sha256sum {} > {}.sha256sum.txt" \; - - uses: ./.github/actions/upload-to-oss-action - with: - key-id: ${{ secrets.OSS_ID }} - key-secret: ${{ secrets.OSS_SECRET }} - endpoint: ${{ secrets.OSS_ENDPOINT }} - bucket: nebula-graph - asset-path: ${{ env.CPACK_DIR }} - target-path: package/${{ steps.tag.outputs.tagnum }} - - uses: ./.github/actions/upload-to-oss-action - with: - key-id: ${{ secrets.OSS_ID }} - key-secret: ${{ secrets.OSS_SECRET }} - endpoint: ${{ secrets.OSS_ENDPOINT }} - bucket: nebula-graph - asset-path: ${{ env.SYMS_DIR }} - target-path: package/${{ steps.tag.outputs.tagnum }}/symbols + - run: | + ossutil64 cp -rf \ + -i ${{ secrets.OSS_ID }} \ + -k ${{ secrets.OSS_SECRET }} \ + -e ${{ secrets.OSS_ENDPOINT }} \ + oss://nebula-graph/rc/${{ steps.tag.outputs.tagnum }} \ + oss://nebula-graph/package/${{ steps.tag.outputs.tagnum }} docker_build: name: docker-build @@ -80,8 +47,6 @@ jobs: with: run: sh -c "find . -mindepth 1 -delete" - uses: actions/checkout@v2 - - name: Check License Header - uses: apache/skywalking-eyes@main - uses: ./.github/actions/tagname-action id: tagname - id: docker @@ -89,24 +54,17 @@ jobs: majorver=$(git tag -l --sort=v:refname | tail -n1 | cut -f1 -d'.') tag="" if [[ $majorver == ${{ steps.tagname.outputs.majorver }} ]]; then - tag="vesoft/nebula-${{ matrix.service }}:latest" + tag="latest" fi echo "::set-output name=tag::$tag" - - uses: docker/setup-qemu-action@v1 - - uses: docker/setup-buildx-action@v1 - - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - uses: docker/build-push-action@v2 - with: - context: . - file: ./docker/Dockerfile.${{ matrix.service }} - platforms: linux/amd64,linux/arm64 - tags: | - vesoft/nebula-${{ matrix.service }}:${{ steps.tagname.outputs.tag }} - vesoft/nebula-${{ matrix.service }}:${{ steps.tagname.outputs.majorver }} - ${{ steps.docker.outputs.tag }} - push: true - build-args: | - BRANCH=${{ steps.tagname.outputs.tag }} + - name: Sync docker images + env: + FROM_IMAGE: docker://${{ secrets.HARBOR_REGISTRY }}/vesoft/nebula-${{ matrix.service }} + TO_IMAGE: docker://docker.io/vesoft/nebula-${{ matrix.service }} + CMD: docker run --rm -ti quay.io/containers/skopeo:v1.4.1 copy -a --src-creds ${{ secrets.HARBOR_USERNAME }}:${{ secrets.HARBOR_PASSWORD }} --dest-creds ${{ secrets.DOCKER_USERNAME }}:${{ secrets.DOCKER_PASSWORD }} + run: | + ${{ env.CMD }} ${{ env.FROM_IMAGE }}:${{ steps.tagname.outputs.tag }} ${{ env.TO_IMAGE }}:${{ steps.tagname.outputs.tag }} + ${{ env.CMD }} ${{ env.FROM_IMAGE }}:${{ steps.tagname.outputs.tag }} ${{ env.TO_IMAGE }}:${{ steps.tagname.outputs.majorver }} + if [[ ! -z "${{ steps.docker.outputs.tag }}" ]]; then + ${{ env.CMD }} ${{ env.FROM_IMAGE }}:${{ steps.tagname.outputs.tag }} ${{ env.TO_IMAGE }}:${{ steps.docker.outputs.tag }} + fi diff --git a/.linters/cpp/checkKeyword.py b/.linters/cpp/checkKeyword.py index af8916cf1a9..11ef9ea941d 100755 --- a/.linters/cpp/checkKeyword.py +++ b/.linters/cpp/checkKeyword.py @@ -8,7 +8,7 @@ import re import sys -PASER_FILE_PATH = 'src/parser/parser.yy' +PARSER_FILE_PATH = 'src/parser/parser.yy' SCANNER_FILE_PATH = 'src/parser/scanner.lex' reserved_key_words = [ @@ -139,7 +139,7 @@ def get_unreserved_keyword(file_path): if len(keywords) == 0: exit(0) - unreserved_key_words = get_unreserved_keyword(PASER_FILE_PATH) + unreserved_key_words = get_unreserved_keyword(PARSER_FILE_PATH) new_key_words = [word for word in keywords if word not in reserved_key_words] if len(new_key_words) == 0: exit(0) diff --git a/.linters/cpp/cpplint.py b/.linters/cpp/cpplint.py index 11a13acf48d..2d53e233bbb 100755 --- a/.linters/cpp/cpplint.py +++ b/.linters/cpp/cpplint.py @@ -641,7 +641,7 @@ # Files to exclude from linting. This is set by the --exclude flag. _excludes = None -# Whether to supress PrintInfo messages +# Whether to suppress PrintInfo messages _quiet = False # The allowed line length of files. @@ -752,7 +752,7 @@ def ParseNolintSuppressions(filename, raw_line, linenum, error): 'Unknown NOLINT error category: %s' % category) -def ProcessGlobalSuppresions(lines): +def ProcessGlobalSuppressions(lines): """Updates the list of global error suppressions. Parses any lint directives in the file that have global effect. @@ -780,7 +780,7 @@ def IsErrorSuppressedByNolint(category, linenum): """Returns true if the specified error category is suppressed on this line. Consults the global error_suppressions map populated by - ParseNolintSuppressions/ProcessGlobalSuppresions/ResetNolintSuppressions. + ParseNolintSuppressions/ProcessGlobalSuppressions/ResetNolintSuppressions. Args: category: str, the category of the error. @@ -1013,7 +1013,7 @@ def __init__(self): self._filters_backup = self.filters[:] self.counting = 'total' # In what way are we counting errors? self.errors_by_category = {} # string to int dict storing error counts - self.quiet = False # Suppress non-error messagess? + self.quiet = False # Suppress non-error messages? # output format: # "emacs" - format that emacs can parse (default) @@ -6202,7 +6202,7 @@ def ProcessFileData(filename, file_extension, lines, error, ResetNolintSuppressions() CheckForCopyright(filename, lines, error) - ProcessGlobalSuppresions(lines) + ProcessGlobalSuppressions(lines) RemoveMultiLineComments(filename, lines, error) clean_lines = CleansedLines(lines) diff --git a/cmake/ThriftGenerate.cmake b/cmake/ThriftGenerate.cmake index 8453a9fcb7a..d82af8ef678 100644 --- a/cmake/ThriftGenerate.cmake +++ b/cmake/ThriftGenerate.cmake @@ -32,7 +32,7 @@ endmacro() # @output_path - The directory where the thrift file lives # # Output: -# file-cpp2-target - A custom target to add a dependenct +# file-cpp2-target - A custom target to add a dependency # ${file-cpp2-HEADERS} - The generated Header Files. # ${file-cpp2-SOURCES} - The generated Source Files. # diff --git a/conf/nebula-graphd.conf.default b/conf/nebula-graphd.conf.default index 43792df94c3..fc2432a20f3 100644 --- a/conf/nebula-graphd.conf.default +++ b/conf/nebula-graphd.conf.default @@ -7,7 +7,7 @@ --enable_optimizer=true # The default charset when a space is created --default_charset=utf8 -# The defaule collate when a space is created +# The default collate when a space is created --default_collate=utf8_bin # Whether to use the configuration obtained from the configuration file --local_config=true diff --git a/conf/nebula-storaged.conf.production b/conf/nebula-storaged.conf.production index f41a16b7d21..8789ebdd08a 100644 --- a/conf/nebula-storaged.conf.production +++ b/conf/nebula-storaged.conf.production @@ -102,7 +102,7 @@ --enable_rocksdb_whole_key_filtering=false ############### misc #################### ---snapshot_part_rate_limit=8388608 +--snapshot_part_rate_limit=10485760 --snapshot_batch_size=1048576 --rebuild_index_part_rate_limit=4194304 --rebuild_index_batch_size=1048576 diff --git a/package/package.sh b/package/package.sh index bab842051e0..23abc71482f 100755 --- a/package/package.sh +++ b/package/package.sh @@ -183,7 +183,7 @@ function _find_dump_syms_tool { function _strip_unnecessary_binaries { for bin in $(ls -1 -F ${build_dir}/bin/ | grep -v [/$] | sed -e '/nebula-metad/d;/nebula-graphd/d;/nebula-storaged/d'); do if ! (strip ${build_dir}/bin/${bin}); then - echo ">>> strip ${bin} faild: $?. <<<" + echo ">>> strip ${bin} failed: $?. <<<" exit 1 fi done @@ -203,7 +203,7 @@ function dump_syms { for bin in nebula-graphd nebula-storaged nebula-metad; do if ! (${dump_syms} ${build_dir}/bin/${bin} > ${syms_dir}/${bin}${ver}.sym); then - echo ">>> dump ${bin} symbols faild: $?. <<<" + echo ">>> dump ${bin} symbols failed: $?. <<<" exit 1 fi done diff --git a/resources/gflags.json b/resources/gflags.json index 48683f75048..e75f960e71a 100644 --- a/resources/gflags.json +++ b/resources/gflags.json @@ -4,7 +4,7 @@ "v", "heartbeat_interval_secs", "meta_client_retry_times", - "slow_op_threshhold_ms", + "slow_op_threshold_ms", "clean_wal_interval_secs", "wal_ttl", "clean_wal_interval_secs", diff --git a/scripts/meta-transfer-tools.sh b/scripts/meta-transfer-tools.sh index 3bb316d47af..6e773ab9493 100755 --- a/scripts/meta-transfer-tools.sh +++ b/scripts/meta-transfer-tools.sh @@ -16,7 +16,7 @@ Usage="this tool is a simple wrapper to scp to copy local folder of metad to ano 1. -f (from) local metad dir \n \ 2. -t (to) remote destination \n \ 3. -u (update) any configs need to be changed \n \ - different configs should be seperated by ':' \n \ + different configs should be separated by ':' \n \ each config has to be the form of "local_ip=172.0.0.1" \n \ \n \ for example \n \ diff --git a/scripts/nebula.service b/scripts/nebula.service index 64739bb20aa..04f38c074f6 100755 --- a/scripts/nebula.service +++ b/scripts/nebula.service @@ -18,7 +18,7 @@ SCRIPT_PATH=$(readlink -f $0) # Directory of this script SCRIPT_DIR=$(dirname ${SCRIPT_PATH}) # Installation directory, i.e. parent of SCRIPT_DIR -# For now we assume that the directory hierachy of the nebula installation is: +# For now we assume that the directory hierarchy of the nebula installation is: # root/bin, root/etc/, root/scripts, etc. INSTALL_ROOT=$(cd ${SCRIPT_DIR}/.. &>/dev/null; pwd) UTILS_PATH=${SCRIPT_DIR}/utils.sh diff --git a/src/clients/meta/FileBasedClusterIdMan.cpp b/src/clients/meta/FileBasedClusterIdMan.cpp index 15212fbc030..7043729cf9e 100644 --- a/src/clients/meta/FileBasedClusterIdMan.cpp +++ b/src/clients/meta/FileBasedClusterIdMan.cpp @@ -31,7 +31,7 @@ bool FileBasedClusterIdMan::persistInFile(ClusterID clusterId, const std::string ::close(fd); return false; } - LOG(INFO) << "Persiste clusterId " << clusterId << " succeeded!"; + LOG(INFO) << "Persist clusterId " << clusterId << " succeeded!"; ::close(fd); return true; } diff --git a/src/clients/meta/MetaClient.cpp b/src/clients/meta/MetaClient.cpp index ea110458291..d3446a8b1ad 100644 --- a/src/clients/meta/MetaClient.cpp +++ b/src/clients/meta/MetaClient.cpp @@ -134,7 +134,7 @@ void MetaClient::heartBeatThreadFunc() { return; } - // if MetaServer has some changes, refesh the localCache_ + // if MetaServer has some changes, refresh the localCache_ loadData(); loadCfg(); } @@ -799,7 +799,7 @@ Status MetaClient::handleResponse(const RESP& resp) { case nebula::cpp2::ErrorCode::E_CONFLICT: return Status::Error("Conflict!"); case nebula::cpp2::ErrorCode::E_INVALID_PARM: - return Status::Error("Invalid parm!"); + return Status::Error("Invalid param!"); case nebula::cpp2::ErrorCode::E_WRONGCLUSTER: return Status::Error("Wrong cluster!"); case nebula::cpp2::ErrorCode::E_STORE_FAILURE: @@ -814,8 +814,8 @@ Status MetaClient::handleResponse(const RESP& resp) { return Status::Error("No running balance plan!"); case nebula::cpp2::ErrorCode::E_NO_VALID_HOST: return Status::Error("No valid host hold the partition!"); - case nebula::cpp2::ErrorCode::E_CORRUPTTED_BALANCE_PLAN: - return Status::Error("No corrupted blance plan!"); + case nebula::cpp2::ErrorCode::E_CORRUPTED_BALANCE_PLAN: + return Status::Error("No corrupted balance plan!"); case nebula::cpp2::ErrorCode::E_INVALID_PASSWORD: return Status::Error("Invalid password!"); case nebula::cpp2::ErrorCode::E_IMPROPER_ROLE: @@ -2424,7 +2424,7 @@ folly::Future> MetaClient::heartbeat() { [](auto client, auto request) { return client->future_heartBeat(request); }, [this](cpp2::HBResp&& resp) -> bool { if (options_.role_ == cpp2::HostRole::STORAGE && options_.clusterId_.load() == 0) { - LOG(INFO) << "Persisit the cluster Id from metad " << resp.get_cluster_id(); + LOG(INFO) << "Persist the cluster Id from metad " << resp.get_cluster_id(); if (FileBasedClusterIdMan::persistInFile(resp.get_cluster_id(), FLAGS_cluster_id_path)) { options_.clusterId_.store(resp.get_cluster_id()); } else { diff --git a/src/clients/meta/MetaClient.h b/src/clients/meta/MetaClient.h index a9b54c8efdf..ea5fc30c890 100644 --- a/src/clients/meta/MetaClient.h +++ b/src/clients/meta/MetaClient.h @@ -139,7 +139,7 @@ using UserRolesMap = std::unordered_map // get user password by account using UserPasswordMap = std::unordered_map; -// config cahce, get config via module and name +// config cache, get config via module and name using MetaConfigMap = std::unordered_map, cpp2::ConfigItem>; @@ -186,7 +186,7 @@ struct MetaClientOptions { // Current host address HostAddr localHost_{"", 0}; - // Current cluster Id, it is requried by storaged only. + // Current cluster Id, it is required by storaged only. std::atomic clusterId_{0}; // If current client being used in storaged. bool inStoraged_ = false; @@ -412,7 +412,7 @@ class MetaClient { folly::Future>> listSnapshots(); - // Opeartions for listener. + // Operations for listener. folly::Future> addListener(GraphSpaceID spaceId, cpp2::ListenerType type, @@ -444,7 +444,7 @@ class MetaClient { StatusOr> getFTClientsFromCache(); - // Opeartions for fulltext index. + // Operations for fulltext index. folly::Future> createFTIndex(const std::string& name, const cpp2::FTIndex& index); @@ -479,7 +479,7 @@ class MetaClient { folly::Future> killQuery( std::unordered_map> killQueries); - // Opeartions for cache. + // Operations for cache. StatusOr getSpaceIdByNameFromCache(const std::string& name); StatusOr getSpaceNameByIdFromCache(GraphSpaceID spaceId); @@ -506,7 +506,7 @@ class MetaClient { StatusOr getEdgeNameByTypeFromCache(const GraphSpaceID& space, const EdgeType edgeType); - // get all lastest version edge + // get all latest version edge StatusOr> getAllEdgeFromCache(const GraphSpaceID& space); PartsMap getPartsMapFromCache(const HostAddr& host); diff --git a/src/clients/storage/GraphStorageClient.cpp b/src/clients/storage/GraphStorageClient.cpp index 206502e10e8..85af874cc19 100644 --- a/src/clients/storage/GraphStorageClient.cpp +++ b/src/clients/storage/GraphStorageClient.cpp @@ -635,7 +635,7 @@ StatusOr> GraphStorageClient::getIdFr if (vidType == PropertyType::INT64) { if (isEdgeProps) { cb = [](const Row& r) -> const VertexID& { - // The first column has to be the src, the thrid column has to be the + // The first column has to be the src, the third column has to be the // dst DCHECK_EQ(Value::Type::INT, r.values[0].type()); DCHECK_EQ(Value::Type::INT, r.values[3].type()); diff --git a/src/clients/storage/StorageClientBase.h b/src/clients/storage/StorageClientBase.h index a5bc2054114..8ee65d321ae 100644 --- a/src/clients/storage/StorageClientBase.h +++ b/src/clients/storage/StorageClientBase.h @@ -60,7 +60,7 @@ class StorageRpcResponse final { ++failedReqs_; } - // A value between [0, 100], representing a precentage + // A value between [0, 100], representing a percentage int32_t completeness() const { std::lock_guard g(*lock_); DCHECK_NE(totalReqsSent_, 0); diff --git a/src/codec/RowReaderV1.cpp b/src/codec/RowReaderV1.cpp index bcbfcd7d97f..84085845b2e 100644 --- a/src/codec/RowReaderV1.cpp +++ b/src/codec/RowReaderV1.cpp @@ -440,7 +440,7 @@ Value RowReaderV1::getVid(int64_t index) const noexcept { /************************************************************ * - * Low -level functions to read from the bytes + * Low-level functions to read from the bytes * ***********************************************************/ int32_t RowReaderV1::readInteger(int64_t offset, int64_t& v) const noexcept { diff --git a/src/codec/RowReaderV1.h b/src/codec/RowReaderV1.h index 55a59bc2bef..22760da1982 100644 --- a/src/codec/RowReaderV1.h +++ b/src/codec/RowReaderV1.h @@ -41,7 +41,7 @@ class RowReaderV1 : public RowReader { private: int32_t headerLen_ = 0; int32_t numBytesForOffset_ = 0; - // Block offet value is composed by two integers. The first one is + // Block offset value is composed by two integers. The first one is // the block offset, the second one is the largest index being visited // in the block. This index is zero-based mutable std::vector> blockOffsets_; @@ -53,7 +53,7 @@ class RowReaderV1 : public RowReader { private: RowReaderV1() = default; - // Process the row header infomation + // Process the row header information // Returns false when the row data is invalid bool processHeader(folly::StringPiece row); @@ -71,7 +71,7 @@ class RowReaderV1 : public RowReader { int64_t skipToNext(int64_t index, int64_t offset) const noexcept; // Skip to the {index}Th field - // The method retuns the offset of the field + // The method returns the offset of the field // It returns a negative number when the data corrupts int64_t skipToField(int64_t index) const noexcept; diff --git a/src/codec/RowWriterV2.cpp b/src/codec/RowWriterV2.cpp index 98954da232b..19378235fc5 100644 --- a/src/codec/RowWriterV2.cpp +++ b/src/codec/RowWriterV2.cpp @@ -57,7 +57,7 @@ RowWriterV2::RowWriterV2(const meta::SchemaProviderIf* schema) header = 0x0E; // 0x08 | 0x06, six bytes for the schema version headerLen_ = 7; } else if (ver < 0x00FFFFFFFFFFFFFF) { - header = 0x0F; // 0x08 | 0x07, severn bytes for the schema version + header = 0x0F; // 0x08 | 0x07, seven bytes for the schema version headerLen_ = 8; } else { LOG(FATAL) << "Schema version too big"; @@ -844,7 +844,7 @@ std::string RowWriterV2::processOutOfSpace() noexcept { // Now let's process all strings for (size_t i = 0; i < schema_->getNumFields(); i++) { auto field = schema_->field(i); - if (field->type() != PropertyType::STRING) { + if (field->type() != PropertyType::STRING && field->type() != PropertyType::GEOGRAPHY) { continue; } diff --git a/src/codec/RowWriterV2.h b/src/codec/RowWriterV2.h index 6b45a76550f..151c0f9dc6e 100644 --- a/src/codec/RowWriterV2.h +++ b/src/codec/RowWriterV2.h @@ -35,7 +35,7 @@ enum class WriteResult { Version 1: v v v 0 0 b b b In version 1, the middle two bits are always zeros. The left three bits - indicats the number of bytes used for the schema version, while the right + indicates the number of bytes used for the schema version, while the right three bits indicates the number of bytes used for the block offsets Version 2: @@ -144,7 +144,7 @@ class RowWriterV2 { const meta::SchemaProviderIf* schema_; std::string buf_; std::vector isSet_; - // Ther number of bytes ocupied by header and the schema version + // The number of bytes occupied by header and the schema version size_t headerLen_; size_t numNullBytes_; size_t approxStrLen_; diff --git a/src/codec/test/RowReaderBenchmark.cpp b/src/codec/test/RowReaderBenchmark.cpp index dc651814f71..54eaa6d889b 100644 --- a/src/codec/test/RowReaderBenchmark.cpp +++ b/src/codec/test/RowReaderBenchmark.cpp @@ -152,7 +152,7 @@ void randomTest(SchemaWriter* schema, } /************************* - * Begining of Tests + * Beginning of Tests ************************/ TEST(RowReader, SequentialShort) { sequentialTest(&schemaShort, dataShortV1, dataShortV2); } @@ -166,7 +166,7 @@ TEST(RowReader, RandomLong) { randomTest(&schemaLong, dataLongV1, dataLongV2, lo ************************/ /************************* - * Begining of benchmarks + * Beginning of benchmarks ************************/ BENCHMARK(seq_read_short_v1, iters) { sequentialRead(&schemaShort, dataShortV1, iters); } BENCHMARK_RELATIVE(seq_read_short_v2, iters) { sequentialRead(&schemaShort, dataShortV2, iters); } diff --git a/src/codec/test/RowWriterBenchmark.cpp b/src/codec/test/RowWriterBenchmark.cpp index 94b4a86985f..ae35c6156ec 100644 --- a/src/codec/test/RowWriterBenchmark.cpp +++ b/src/codec/test/RowWriterBenchmark.cpp @@ -64,7 +64,7 @@ void writeDataV2(SchemaWriter* schema, int32_t iters) { } /************************* - * Begining of benchmarks + * Beginning of benchmarks ************************/ BENCHMARK(WriteShortRowV1, iters) { writeDataV1(&schemaShort, iters); } diff --git a/src/codec/test/RowWriterV2Test.cpp b/src/codec/test/RowWriterV2Test.cpp index 527a46b8492..c1b6be0eafd 100644 --- a/src/codec/test/RowWriterV2Test.cpp +++ b/src/codec/test/RowWriterV2Test.cpp @@ -27,6 +27,22 @@ const DateTime dt = {2020, 2, 20, 10, 30, 45, 0}; const Value sVal("Hello world!"); const Value iVal(64); const Time t = {10, 30, 45, 0}; +// POINT(179.0 89.9) +const Geography geogPoint = Point(Coordinate(179.0, 89.9)); +// LINESTRING(0 1, 1 2, 3 7) +const Geography geogLineString = + LineString(std::vector{Coordinate(0, 1), Coordinate(1, 2), Coordinate(3, 7)}); +// POLYGON((-108.7 35.0, -100.0 46.5, -90.7 34.9, -108.7 35.0), +// (-100.1 41.4, -102.9 37.6, -96.8 37.5, -100.1 41.4)) +const Geography geogPolygon = Polygon( + std::vector>{std::vector{Coordinate(-108.7, 35.0), + Coordinate(-100.0, 46.5), + Coordinate(-90.7, 34.9), + Coordinate(-108.7, 35.0)}, + std::vector{Coordinate(-100.1, 41.4), + Coordinate(-102.9, 37.6), + Coordinate(-96.8, 37.5), + Coordinate(-100.1, 41.4)}}); TEST(RowWriterV2, NoDefaultValue) { SchemaWriter schema(12 /*Schema version*/); @@ -45,6 +61,13 @@ TEST(RowWriterV2, NoDefaultValue) { schema.appendCol("Col13", PropertyType::DATETIME); schema.appendCol("Col14", PropertyType::INT64, 0, true); schema.appendCol("Col15", PropertyType::INT32, 0, true); + schema.appendCol( + "Col16", PropertyType::GEOGRAPHY, 0, false, nullptr, meta::cpp2::GeoShape::POINT); + schema.appendCol( + "Col17", PropertyType::GEOGRAPHY, 0, false, nullptr, meta::cpp2::GeoShape::LINESTRING); + schema.appendCol( + "Col18", PropertyType::GEOGRAPHY, 0, false, nullptr, meta::cpp2::GeoShape::POLYGON); + schema.appendCol("Col19", PropertyType::GEOGRAPHY, 0, true, nullptr, meta::cpp2::GeoShape::ANY); ASSERT_EQ(Value::Type::STRING, sVal.type()); ASSERT_EQ(Value::Type::INT, iVal.type()); @@ -65,6 +88,10 @@ TEST(RowWriterV2, NoDefaultValue) { EXPECT_EQ(WriteResult::SUCCEEDED, writer1.set(12, dt)); EXPECT_EQ(WriteResult::SUCCEEDED, writer1.setNull(13)); // Purposely skip the col15 + EXPECT_EQ(WriteResult::SUCCEEDED, writer1.set(15, geogPoint)); + EXPECT_EQ(WriteResult::SUCCEEDED, writer1.set(16, geogLineString)); + EXPECT_EQ(WriteResult::SUCCEEDED, writer1.set(17, geogPolygon)); + // Purposely skip the col19 ASSERT_EQ(WriteResult::SUCCEEDED, writer1.finish()); RowWriterV2 writer2(&schema); @@ -83,10 +110,16 @@ TEST(RowWriterV2, NoDefaultValue) { EXPECT_EQ(WriteResult::SUCCEEDED, writer2.set("Col13", dt)); EXPECT_EQ(WriteResult::SUCCEEDED, writer2.setNull("Col14")); // Purposely skip the col15 + EXPECT_EQ(WriteResult::SUCCEEDED, writer2.set("Col16", geogPoint)); + EXPECT_EQ(WriteResult::SUCCEEDED, writer2.set("Col17", geogLineString)); + EXPECT_EQ(WriteResult::SUCCEEDED, writer2.set("Col18", geogPolygon)); + // Purposely skip the col19 ASSERT_EQ(WriteResult::SUCCEEDED, writer2.finish()); std::string encoded1 = std::move(writer1).moveEncodedStr(); std::string encoded2 = writer2.getEncodedStr(); + LOG(INFO) << "encoded1, size=" << encoded1.size() << "content=" << folly::hexlify(encoded1); + LOG(INFO) << "encoded2, size=" << encoded2.size() << "content=" << folly::hexlify(encoded2); auto reader1 = RowReaderWrapper::getRowReader(&schema, encoded1); auto reader2 = RowReaderWrapper::getRowReader(&schema, encoded2); @@ -175,7 +208,7 @@ TEST(RowWriterV2, NoDefaultValue) { EXPECT_EQ(t, v1.getTime()); EXPECT_EQ(v1, v2); - // Col1333 + // Col13 v1 = reader1->getValueByName("Col13"); v2 = reader2->getValueByIndex(12); EXPECT_EQ(Value::Type::DATETIME, v1.type()); @@ -193,6 +226,33 @@ TEST(RowWriterV2, NoDefaultValue) { v2 = reader2->getValueByIndex(14); EXPECT_EQ(Value::Type::NULLVALUE, v1.type()); EXPECT_EQ(v1, v2); + + // Col16 + v1 = reader1->getValueByName("Col16"); + v2 = reader2->getValueByIndex(15); + EXPECT_EQ(Value::Type::GEOGRAPHY, v1.type()); + EXPECT_EQ(geogPoint, v1.getGeography()); + EXPECT_EQ(v1, v2); + + // Col17 + v1 = reader1->getValueByName("Col17"); + v2 = reader2->getValueByIndex(16); + EXPECT_EQ(Value::Type::GEOGRAPHY, v1.type()); + EXPECT_EQ(geogLineString, v1.getGeography()); + EXPECT_EQ(v1, v2); + + // Col18 + v1 = reader1->getValueByName("Col18"); + v2 = reader2->getValueByIndex(17); + EXPECT_EQ(Value::Type::GEOGRAPHY, v1.type()); + EXPECT_EQ(geogPolygon, v1.getGeography()); + EXPECT_EQ(v1, v2); + + // Col19 + v1 = reader1->getValueByName("Col19"); + v2 = reader2->getValueByIndex(18); + EXPECT_EQ(Value::Type::NULLVALUE, v1.type()); + EXPECT_EQ(v1, v2); } TEST(RowWriterV2, WithDefaultValue) { diff --git a/src/common/base/ConcurrentLRUCache.h b/src/common/base/ConcurrentLRUCache.h index 775d175f713..7893039319e 100644 --- a/src/common/base/ConcurrentLRUCache.h +++ b/src/common/base/ConcurrentLRUCache.h @@ -159,7 +159,7 @@ class ConcurrentLRUCache final { /** It is copied from boost::compute::detail::LRU. The differences: - 1. Add methed evict(const K& key); + 1. Add method evict(const K& key); 2. Instead std::map with std::unordered_map 3. Update the code style. 4. Add stats diff --git a/src/common/base/SignalHandler.h b/src/common/base/SignalHandler.h index 5950eacec6c..5e639d75214 100644 --- a/src/common/base/SignalHandler.h +++ b/src/common/base/SignalHandler.h @@ -12,7 +12,7 @@ #include "common/base/Status.h" /** - * SignalHandler is a singleton to do the basic signal hanling, + * SignalHandler is a singleton to do the basic signal handling, * mainly used in a daemon executable. * * By default, it ignores SIGPIPE and SIGHUP as we usually do. @@ -32,7 +32,7 @@ class SignalHandler final { /** * To install one or several signals to handle. - * Upon any signal arrives, the cooresponding handler would be invoked, + * Upon any signal arrives, the corresponding handler would be invoked, * with an argument holding the informations about the signal and the sender. * The handler typically prints out the info and do some other things, * e.g. stop the process on SIGTERM. diff --git a/src/common/base/SlowOpTracker.cpp b/src/common/base/SlowOpTracker.cpp index 5a81c7db52d..0986643d9fc 100644 --- a/src/common/base/SlowOpTracker.cpp +++ b/src/common/base/SlowOpTracker.cpp @@ -8,4 +8,4 @@ #include "common/base/Base.h" #include "common/time/WallClock.h" -DEFINE_int64(slow_op_threshhold_ms, 50, "default threshhold for slow operation"); +DEFINE_int64(slow_op_threshold_ms, 100, "default threshold for slow operation"); diff --git a/src/common/base/SlowOpTracker.h b/src/common/base/SlowOpTracker.h index 5d50628cf25..63c86597298 100644 --- a/src/common/base/SlowOpTracker.h +++ b/src/common/base/SlowOpTracker.h @@ -9,7 +9,7 @@ #include "common/base/Base.h" #include "common/time/WallClock.h" -DECLARE_int64(slow_op_threshhold_ms); +DECLARE_int64(slow_op_threshold_ms); namespace nebula { @@ -19,12 +19,12 @@ class SlowOpTracker { ~SlowOpTracker() = default; - bool slow(int64_t threshhold = 0) { + bool slow(int64_t threshold = 0) { dur_ = time::WallClock::fastNowInMilliSec() - startMs_; if (dur_ < 0) { dur_ = 0; } - return threshhold > 0 ? dur_ > threshhold : dur_ > FLAGS_slow_op_threshhold_ms; + return threshold > 0 ? dur_ > threshold : dur_ > FLAGS_slow_op_threshold_ms; } void output(const std::string& prefix, const std::string& msg) { diff --git a/src/common/base/Status.h b/src/common/base/Status.h index 60e74fcbf2b..de7c9dbc471 100644 --- a/src/common/base/Status.h +++ b/src/common/base/Status.h @@ -136,7 +136,7 @@ class Status final { // If some kind of error really needs to be distinguished with others using a // specific code, other than a general code and specific msg, you could add a - // new code below, e.g. kSomeError, and add the cooresponding + // new code below, e.g. kSomeError, and add the corresponding // STATUS_GENERATOR(SomeError) enum Code : uint16_t { // OK diff --git a/src/common/base/StatusOr.h b/src/common/base/StatusOr.h index 6b668402ab3..3962f34642c 100644 --- a/src/common/base/StatusOr.h +++ b/src/common/base/StatusOr.h @@ -63,7 +63,7 @@ class StatusOr final { // `StatusOr' contains neither a Status nor a value // in the default-constructed case. // From the semantics aspect, it must have been associated with - // a Status or value eventualy before being used. + // a Status or value eventually before being used. StatusOr() { state_ = kVoid; } // Destruct the `Status' or value if it's holding one. @@ -172,7 +172,7 @@ class StatusOr final { return *this; } - // Move assigment operator from a rvalue of `StatusOr' + // Move assignment operator from a rvalue of `StatusOr' template >> StatusOr &operator=(StatusOr &&rhs) noexcept { reset(); @@ -190,7 +190,7 @@ class StatusOr final { return *this; } - // Move assigment operator from a rvalue of any compatible type with `T' + // Move assignment operator from a rvalue of any compatible type with `T' template >> StatusOr &operator=(U &&value) noexcept { destruct(); @@ -236,7 +236,7 @@ class StatusOr final { } // Return the non-const lvalue reference to the associated value - // `ok()' is DCHECKed + // `ok()' is DCHECK'd T &value() & { DCHECK(ok()); return variant_.value_; diff --git a/src/common/base/StringUnorderedMap.h b/src/common/base/StringUnorderedMap.h index cdedae10036..081e4d68786 100644 --- a/src/common/base/StringUnorderedMap.h +++ b/src/common/base/StringUnorderedMap.h @@ -41,7 +41,7 @@ class StringUnorderedMap { /****************************************** * - * Assignmets + * Assignments * *****************************************/ StringUnorderedMap& operator=(const StringUnorderedMap& other); diff --git a/src/common/conf/Configuration.cpp b/src/common/conf/Configuration.cpp index a250307d868..c5d3d7ba0e8 100644 --- a/src/common/conf/Configuration.cpp +++ b/src/common/conf/Configuration.cpp @@ -180,7 +180,7 @@ Status Configuration::fetchAsIntArray(const char *key, std::vector &val try { val.emplace_back(entry.asInt()); } catch (const std::exception &ex) { - // Avoid format sercure by literal + // Avoid format secure by literal return Status::Error("%s", ex.what()); } } @@ -201,7 +201,7 @@ Status Configuration::fetchAsDoubleArray(const char *key, std::vector &v try { val.emplace_back(entry.asDouble()); } catch (const std::exception &ex) { - // Avoid format sercure by literal + // Avoid format secure by literal return Status::Error("%s", ex.what()); } } @@ -222,7 +222,7 @@ Status Configuration::fetchAsBoolArray(const char *key, std::vector &val) try { val.emplace_back(entry.asBool()); } catch (const std::exception &ex) { - // Avoid format sercure by literal + // Avoid format secure by literal return Status::Error("%s", ex.what()); } } @@ -243,7 +243,7 @@ Status Configuration::fetchAsStringArray(const char *key, std::vector proces try { processor(key.asString()); } catch (const std::exception &ex) { - // Avoid format sercure by literal + // Avoid format secure by literal return Status::Error("%s", ex.what()); } } @@ -270,7 +270,7 @@ Status Configuration::forEachItem( try { processor(item.first.asString(), item.second); } catch (const std::exception &ex) { - // Avoid format sercure by literal + // Avoid format secure by literal return Status::Error("%s", ex.what()); } } diff --git a/src/common/conf/test/ConfigurationTest.cpp b/src/common/conf/test/ConfigurationTest.cpp index 10043fe1a4f..6ed00c7d145 100644 --- a/src/common/conf/test/ConfigurationTest.cpp +++ b/src/common/conf/test/ConfigurationTest.cpp @@ -63,7 +63,7 @@ TEST(Configuration, Basic) { } { bool val; - status = conf.fetchAsBool("nonexist", val); + status = conf.fetchAsBool("nonexistent", val); ASSERT_FALSE(status.ok()) << status.toString(); } } diff --git a/src/common/datatypes/Date.h b/src/common/datatypes/Date.h index 5e6087e8a4b..80b58243bb6 100644 --- a/src/common/datatypes/Date.h +++ b/src/common/datatypes/Date.h @@ -12,7 +12,7 @@ namespace nebula { -// In nebula only store UTC time, and the interpretion of time value based on +// In nebula only store UTC time, and the interpretation of time value based on // the timezone configuration in current system. extern const int64_t kDaysSoFar[]; diff --git a/src/common/datatypes/Edge.cpp b/src/common/datatypes/Edge.cpp index ea11b5ec240..fad349cef7b 100644 --- a/src/common/datatypes/Edge.cpp +++ b/src/common/datatypes/Edge.cpp @@ -131,6 +131,16 @@ void Edge::clear() { props.clear(); } +bool Edge::keyEqual(const Edge& rhs) const { + if (type != rhs.type && type != -rhs.type) { + return false; + } + if (type == rhs.type) { + return src == rhs.src && dst == rhs.dst && ranking == rhs.ranking; + } + return src == rhs.dst && dst == rhs.src && ranking == rhs.ranking; +} + } // namespace nebula namespace std { diff --git a/src/common/datatypes/Edge.h b/src/common/datatypes/Edge.h index 65bd439855d..5fe10af251b 100644 --- a/src/common/datatypes/Edge.h +++ b/src/common/datatypes/Edge.h @@ -68,6 +68,8 @@ struct Edge { bool contains(const Value& key) const; const Value& value(const std::string& key) const; + + bool keyEqual(const Edge& rhs) const; }; inline std::ostream& operator<<(std::ostream& os, const Edge& v) { return os << v.toString(); } diff --git a/src/common/datatypes/test/CMakeLists.txt b/src/common/datatypes/test/CMakeLists.txt index 2ec47fd1962..e2feb822850 100644 --- a/src/common/datatypes/test/CMakeLists.txt +++ b/src/common/datatypes/test/CMakeLists.txt @@ -54,7 +54,7 @@ nebula_add_test( nebula_add_test( NAME - structral_value_test + structural_value_test SOURCES PathTest.cpp EdgeTest.cpp diff --git a/src/common/datatypes/test/ValueTest.cpp b/src/common/datatypes/test/ValueTest.cpp index 8a89ad2422d..b27253e935d 100644 --- a/src/common/datatypes/test/ValueTest.cpp +++ b/src/common/datatypes/test/ValueTest.cpp @@ -627,7 +627,7 @@ TEST(Value, TypeCast) { Value vNull(NullType::__NULL__); Value vIntMin(std::numeric_limits::min()); Value vIntMax(std::numeric_limits::max()); - Value vFloatMin(std::numeric_limits::lowest()); // non-negtive + Value vFloatMin(std::numeric_limits::lowest()); // non-negative Value vFloatMax(std::numeric_limits::max()); { @@ -720,7 +720,7 @@ TEST(Value, TypeCast) { EXPECT_EQ(Value::Type::FLOAT, vf.type()); EXPECT_EQ(vf.getFloat(), std::numeric_limits::max()); - // Invlaid string + // Invalid string vf = Value("12abc").toFloat(); EXPECT_EQ(Value::kNullValue, vf); @@ -788,7 +788,7 @@ TEST(Value, TypeCast) { vi = Value("-9223372036854775809").toInt(); EXPECT_EQ(Value::kNullOverflow, vi); - // Invlaid string + // Invalid string vi = Value("12abc").toInt(); EXPECT_EQ(Value::kNullValue, vi); @@ -1071,7 +1071,7 @@ TEST(Value, DecodeEncode) { // time Value(Time{1, 2, 3, 4}), - // datatime + // datetime Value(DateTime{1, 2, 3, 4, 5, 6, 7}), // vertex diff --git a/src/common/datatypes/test/ValueToJsonTest.cpp b/src/common/datatypes/test/ValueToJsonTest.cpp index fa20b9bf5b9..a35220fc78a 100644 --- a/src/common/datatypes/test/ValueToJsonTest.cpp +++ b/src/common/datatypes/test/ValueToJsonTest.cpp @@ -52,20 +52,20 @@ TEST(ValueToJson, vertex) { tag2, }})); { - dynamic expectedVeretxJson = dynamic::object("tagName.prop", 2)("tagName1.prop1", 2)( + dynamic expectedVertexJson = dynamic::object("tagName.prop", 2)("tagName1.prop1", 2)( "tagName1.prop2", nullptr)("tagName1.prop3", "123"); - ASSERT_EQ(expectedVeretxJson, vertexStrVid.toJson()); + ASSERT_EQ(expectedVertexJson, vertexStrVid.toJson()); - dynamic expectedVeretxMetaJson = dynamic::object("id", "Vid")("type", "vertex"); - ASSERT_EQ(expectedVeretxMetaJson, vertexStrVid.getMetaData()); + dynamic expectedVertexMetaJson = dynamic::object("id", "Vid")("type", "vertex"); + ASSERT_EQ(expectedVertexMetaJson, vertexStrVid.getMetaData()); } { - dynamic expectedVeretxJson = dynamic::object("tagName.prop", 2)("tagName1.prop1", 2)( + dynamic expectedVertexJson = dynamic::object("tagName.prop", 2)("tagName1.prop1", 2)( "tagName1.prop2", nullptr)("tagName1.prop3", "123"); - ASSERT_EQ(expectedVeretxJson, vertexIntVid.toJson()); + ASSERT_EQ(expectedVertexJson, vertexIntVid.toJson()); - dynamic expectedVeretxMetaJson = dynamic::object("id", 001)("type", "vertex"); - ASSERT_EQ(expectedVeretxMetaJson, vertexIntVid.getMetaData()); + dynamic expectedVertexMetaJson = dynamic::object("id", 001)("type", "vertex"); + ASSERT_EQ(expectedVertexMetaJson, vertexIntVid.getMetaData()); } } @@ -159,7 +159,7 @@ TEST(ValueToJson, Set) { DateTime(2021, 12, 21, 13, 30, 15, 0)})); // datetime dynamic expectedSetJsonObj = dynamic::array( 2, 2.33, true, "str", "2021-12-21", "13:30:15.000000Z", "2021-12-21T13:30:15.0Z"); - // The underlying data strcuture is unordered_set, so sort before the comparison + // The underlying data structure is unordered_set, so sort before the comparison auto actualJson = set.toJson(); std::sort(actualJson.begin(), actualJson.end()); std::sort(expectedSetJsonObj.begin(), expectedSetJsonObj.end()); @@ -246,7 +246,7 @@ TEST(ValueToJson, DecodeEncode) { // time Value(Time{1, 2, 3, 4}), - // datatime + // datetime Value(DateTime{1, 2, 3, 4, 5, 6, 7}), // vertex diff --git a/src/common/expression/Expression.cpp b/src/common/expression/Expression.cpp index 113e74be259..01e8388c848 100644 --- a/src/common/expression/Expression.cpp +++ b/src/common/expression/Expression.cpp @@ -560,7 +560,7 @@ std::ostream& operator<<(std::ostream& os, Expression::Kind kind) { os << "Equal"; break; case Expression::Kind::kRelNE: - os << "NotEuqal"; + os << "NotEqual"; break; case Expression::Kind::kRelLT: os << "LessThan"; diff --git a/src/common/expression/LabelAttributeExpression.h b/src/common/expression/LabelAttributeExpression.h index 633797350a6..809b3c44a5b 100644 --- a/src/common/expression/LabelAttributeExpression.h +++ b/src/common/expression/LabelAttributeExpression.h @@ -67,11 +67,11 @@ class LabelAttributeExpression final : public Expression { } void writeTo(Encoder&) const override { - LOG(FATAL) << "LabelAttributeExpression not supporte to encode."; + LOG(FATAL) << "LabelAttributeExpression not supported to encode."; } void resetFrom(Decoder&) override { - LOG(FATAL) << "LabelAttributeExpression not supporte to decode."; + LOG(FATAL) << "LabelAttributeExpression not supported to decode."; } private: diff --git a/src/common/expression/PathBuildExpression.cpp b/src/common/expression/PathBuildExpression.cpp index fba2c5791e3..03a274b83b8 100644 --- a/src/common/expression/PathBuildExpression.cpp +++ b/src/common/expression/PathBuildExpression.cpp @@ -26,46 +26,60 @@ const Value& PathBuildExpression::eval(ExpressionContext& ctx) { for (size_t i = 1; i < items_.size(); ++i) { auto& value = items_[i]->eval(ctx); - if (value.isEdge()) { + if (!buildPath(value, path)) { + return Value::kNullBadData; + } + } + + result_ = path; + return result_; +} + +bool PathBuildExpression::buildPath(const Value& value, Path& path) const { + switch (value.type()) { + case Value::Type::EDGE: { + Step step; if (!path.steps.empty()) { - const auto& lastStep = path.steps.back(); - const auto& edge = value.getEdge(); - if (lastStep.dst.vid != edge.src) { - return Value::kNullBadData; - } + getEdge(value, path.steps.back().dst.vid, step); + } else { + getEdge(value, path.src.vid, step); } - Step step; - getEdge(value, step); path.steps.emplace_back(std::move(step)); - } else if (value.isVertex()) { + break; + } + case Value::Type::VERTEX: { if (path.steps.empty()) { - return Value::kNullBadData; + if (path.src.vid == value.getVertex().vid) { + return true; + } + return false; } auto& lastStep = path.steps.back(); - const auto& vert = value.getVertex(); - if (lastStep.dst.vid != vert.vid) { - return Value::kNullBadData; - } getVertex(value, lastStep.dst); - } else if (value.isPath()) { + break; + } + case Value::Type::PATH: { const auto& p = value.getPath(); if (!path.steps.empty()) { auto& lastStep = path.steps.back(); - if (lastStep.dst.vid != p.src.vid) { - return Value::kNullBadData; - } lastStep.dst = p.src; } path.steps.insert(path.steps.end(), p.steps.begin(), p.steps.end()); - } else { - if ((i & 1) == 1 || path.steps.empty() || !getVertex(value, path.steps.back().dst)) { - return Value::kNullBadData; + break; + } + case Value::Type::LIST: { + for (const auto& val : value.getList().values) { + if (!buildPath(val, path)) { + return false; + } } + break; + } + default: { + return false; } } - - result_ = path; - return result_; + return true; } bool PathBuildExpression::getVertex(const Value& value, Vertex& vertex) const { @@ -84,18 +98,26 @@ bool PathBuildExpression::getVertex(const Value& value, Vertex& vertex) const { return false; } -bool PathBuildExpression::getEdge(const Value& value, Step& step) const { - if (value.isEdge()) { - const auto& edge = value.getEdge(); +bool PathBuildExpression::getEdge(const Value& value, const Value& lastStepVid, Step& step) const { + if (!value.isEdge()) { + return false; + } + + const auto& edge = value.getEdge(); + if (lastStepVid == edge.src) { step.type = edge.type; step.name = edge.name; step.ranking = edge.ranking; step.props = edge.props; step.dst.vid = edge.dst; - return true; + } else { + step.type = -edge.type; + step.name = edge.name; + step.ranking = edge.ranking; + step.props = edge.props; + step.dst.vid = edge.src; } - - return false; + return true; } bool PathBuildExpression::operator==(const Expression& rhs) const { diff --git a/src/common/expression/PathBuildExpression.h b/src/common/expression/PathBuildExpression.h index f1f03e62726..aaea497db9d 100644 --- a/src/common/expression/PathBuildExpression.h +++ b/src/common/expression/PathBuildExpression.h @@ -56,7 +56,9 @@ class PathBuildExpression final : public Expression { bool getVertex(const Value& value, Vertex& vertex) const; - bool getEdge(const Value& value, Step& step) const; + bool getEdge(const Value& value, const Value& lastStepVid, Step& step) const; + + bool buildPath(const Value& value, Path& path) const; private: std::vector items_; diff --git a/src/common/expression/PropertyExpression.h b/src/common/expression/PropertyExpression.h index f18f2831af6..4f8c86f34e4 100644 --- a/src/common/expression/PropertyExpression.h +++ b/src/common/expression/PropertyExpression.h @@ -16,7 +16,7 @@ constexpr char const kSrcRef[] = "$^"; constexpr char const kDstRef[] = "$$"; // Base abstract expression of getting properties. -// An expresion of getting props is consisted with 3 parts: +// An expression of getting props is consisted with 3 parts: // 1. reference, e.g. $-, $, $^, $$ // 2. symbol, a symbol name, e.g. tag_name, edge_name, variable_name, // 3. property, property name. diff --git a/src/common/expression/VariableExpression.h b/src/common/expression/VariableExpression.h index 245e60e9cae..23210860c85 100644 --- a/src/common/expression/VariableExpression.h +++ b/src/common/expression/VariableExpression.h @@ -92,11 +92,11 @@ class VersionedVariableExpression final : public Expression { : Expression(pool, Kind::kVersionedVar), var_(var), version_(version) {} void writeTo(Encoder&) const override { - LOG(FATAL) << "VersionedVairableExpression not support to encode."; + LOG(FATAL) << "VersionedVariableExpression not support to encode."; } void resetFrom(Decoder&) override { - LOG(FATAL) << "VersionedVairableExpression not support to decode."; + LOG(FATAL) << "VersionedVariableExpression not support to decode."; } private: diff --git a/src/common/expression/test/ConstantExpressionTest.cpp b/src/common/expression/test/ConstantExpressionTest.cpp index 55eecb27e6d..e20a0558942 100644 --- a/src/common/expression/test/ConstantExpressionTest.cpp +++ b/src/common/expression/test/ConstantExpressionTest.cpp @@ -16,8 +16,8 @@ TEST_F(ExpressionTest, Constant) { EXPECT_EQ(eval, 1); } { - auto doubl = ConstantExpression::make(&pool, 1.0); - auto eval = Expression::eval(doubl, gExpCtxt); + auto double_ = ConstantExpression::make(&pool, 1.0); + auto eval = Expression::eval(double_, gExpCtxt); EXPECT_EQ(eval.type(), Value::Type::FLOAT); EXPECT_EQ(eval, 1.0); } diff --git a/src/common/expression/test/ExpressionBenchmark.cpp b/src/common/expression/test/ExpressionBenchmark.cpp index 45f8eec2b5c..899250b4cea 100644 --- a/src/common/expression/test/ExpressionBenchmark.cpp +++ b/src/common/expression/test/ExpressionBenchmark.cpp @@ -197,7 +197,7 @@ getEdgeProp(ger_edge_prop_int) 51.88ns 19.27M getEdgeProp(ger_edge_prop_string) 88.41ns 11.31M ============================================================================ -The latest(2020/07/13) vesion of the implementation of expressions, +The latest(2020/07/13) version of the implementation of expressions, which return Value for getting edge props and src props in ExpressionContext. ============================================================================ ExpressionBenchmark.cpprelative time/iter iters/s diff --git a/src/common/expression/test/ExpressionContextMock.cpp b/src/common/expression/test/ExpressionContextMock.cpp index b0318536710..9a54ce323d1 100644 --- a/src/common/expression/test/ExpressionContextMock.cpp +++ b/src/common/expression/test/ExpressionContextMock.cpp @@ -36,9 +36,9 @@ std::unordered_map ExpressionContextMock::vals_ = { {"srcProperty", Value(13)}, {"dstProperty", Value(3)}, - {"path_src", Value("1")}, + {"path_src", Value(Vertex("1", {}))}, {"path_edge1", Value(Edge("1", "2", 1, "edge", 0, {}))}, - {"path_v1", Value("2")}, + {"path_v1", Value(Vertex("2", {}))}, {"path_edge2", Value(Edge("2", "3", 1, "edge", 0, {}))}, {"path_v2", Value(Vertex("3", {}))}, {"path_edge3", Value(Edge("3", "4", 1, "edge", 0, {}))}, diff --git a/src/common/expression/test/ExpressionContextMock.h b/src/common/expression/test/ExpressionContextMock.h index 9f91016d8fc..dda2d5369c0 100644 --- a/src/common/expression/test/ExpressionContextMock.h +++ b/src/common/expression/test/ExpressionContextMock.h @@ -112,7 +112,7 @@ class ExpressionContextMock final : public ExpressionContext { Value getColumn(int32_t index) const override; void setVar(const std::string& var, Value val) override { - // used by tests of list comprehesion, predicate or reduce + // used by tests of list comprehension, predicate or reduce if (var == "n" || var == "p" || var == "totalNum") { vals_.erase(var); vals_[var] = val; diff --git a/src/common/fs/FileUtils.h b/src/common/fs/FileUtils.h index b237ef7ec65..d87c59ec227 100644 --- a/src/common/fs/FileUtils.h +++ b/src/common/fs/FileUtils.h @@ -50,7 +50,7 @@ class FileUtils final { // Tell if stdin attached to a TTY static bool isStdinTTY(); - // Tell if stdout atached to a TTY + // Tell if stdout attached to a TTY static bool isStdoutTTY(); // Tell if stderr attached to a TTY static bool isStderrTTY(); diff --git a/src/common/fs/test/FileUtilsTest.cpp b/src/common/fs/test/FileUtilsTest.cpp index 9e15669d51e..adeff0e3351 100644 --- a/src/common/fs/test/FileUtilsTest.cpp +++ b/src/common/fs/test/FileUtilsTest.cpp @@ -161,7 +161,7 @@ TEST(FileUtils, removeDirRecursively) { fd = mkstemp(fileTemp); ASSERT_EQ(close(fd), 0); - // Recursively removal shold succeed + // Recursively removal should succeed EXPECT_TRUE(FileUtils::remove(dirTemp, true)); // Verify the directory is gone diff --git a/src/common/fs/test/TempFileTest.cpp b/src/common/fs/test/TempFileTest.cpp index 0014afb218b..9c64e6fe93d 100644 --- a/src/common/fs/test/TempFileTest.cpp +++ b/src/common/fs/test/TempFileTest.cpp @@ -12,7 +12,7 @@ namespace nebula { namespace fs { TEST(TempFile, Basic) { - // auto deletiong + // auto deletion { const char *path = "/tmp/tmp.XXXXXX"; std::string actual_path; diff --git a/src/common/function/FunctionManager.cpp b/src/common/function/FunctionManager.cpp index 2a38b6736f3..4bf3ac2cd2d 100644 --- a/src/common/function/FunctionManager.cpp +++ b/src/common/function/FunctionManager.cpp @@ -413,6 +413,7 @@ std::unordered_map> FunctionManager::typ Value::Type::FLOAT}, Value::Type::LIST), }}, + {"is_edge", {TypeSignature({Value::Type::EDGE}, Value::Type::BOOL)}}, }; // static @@ -805,7 +806,7 @@ FunctionManager::FunctionManager() { }; } { - // return the mathmatical constant PI + // return the mathematical constant PI auto &attr = functions_["pi"]; attr.minArity_ = 0; attr.maxArity_ = 0; @@ -1643,7 +1644,7 @@ FunctionManager::FunctionManager() { } { auto &attr = functions_["date"]; - // 0 for corrent time + // 0 for current time // 1 for string or map attr.minArity_ = 0; attr.maxArity_ = 1; @@ -1715,7 +1716,7 @@ FunctionManager::FunctionManager() { } { auto &attr = functions_["datetime"]; - // 0 for corrent time + // 0 for current time // 1 for string or map attr.minArity_ = 0; attr.maxArity_ = 1; @@ -1945,6 +1946,41 @@ FunctionManager::FunctionManager() { } }; } + { + auto &attr = functions_["none_direct_dst"]; + attr.minArity_ = 1; + attr.maxArity_ = 1; + attr.isPure_ = true; + attr.body_ = [](const auto &args) -> Value { + switch (args[0].get().type()) { + case Value::Type::NULLVALUE: { + return Value::kNullValue; + } + case Value::Type::EDGE: { + const auto &edge = args[0].get().getEdge(); + return edge.dst; + } + case Value::Type::VERTEX: { + const auto &v = args[0].get().getVertex(); + return v.vid; + } + case Value::Type::LIST: { + const auto &listVal = args[0].get().getList(); + auto &lastVal = listVal.values.back(); + if (lastVal.isEdge()) { + return lastVal.getEdge().dst; + } else if (lastVal.isVertex()) { + return lastVal.getVertex().vid; + } else { + return Value::kNullBadType; + } + } + default: { + return Value::kNullBadType; + } + } + }; + } { auto &attr = functions_["rank"]; attr.minArity_ = 1; @@ -2636,6 +2672,13 @@ FunctionManager::FunctionManager() { return List(vals); }; } + { + auto &attr = functions_["is_edge"]; + attr.minArity_ = 1; + attr.maxArity_ = 1; + attr.isPure_ = true; + attr.body_ = [](const auto &args) -> Value { return args[0].get().isEdge(); }; + } } // NOLINT // static diff --git a/src/common/function/test/FunctionManagerTest.cpp b/src/common/function/test/FunctionManagerTest.cpp index 9305c788e59..a34a88e0d06 100644 --- a/src/common/function/test/FunctionManagerTest.cpp +++ b/src/common/function/test/FunctionManagerTest.cpp @@ -32,7 +32,7 @@ class FunctionManagerTest : public ::testing::Test { auto result = FunctionManager::get(expr, args.size()); if (!result.ok()) { return ::testing::AssertionFailure() - << "Can't get fuction " << expr << " with " << args.size() << " parameters."; + << "Can't get function " << expr << " with " << args.size() << " parameters."; } auto res = result.value()(argsRef); if (res.type() != expect.type()) { @@ -53,7 +53,7 @@ class FunctionManagerTest : public ::testing::Test { auto result = FunctionManager::get(expr, args.size()); if (!result.ok()) { return ::testing::AssertionFailure() - << "Can't get fuction " << expr << " with " << args.size() << " parameters."; + << "Can't get function " << expr << " with " << args.size() << " parameters."; } auto res = result.value()(argsRef); if (res.type() != expectType) { @@ -68,7 +68,7 @@ class FunctionManagerTest : public ::testing::Test { auto result = FunctionManager::get(expr, args.size()); if (!result.ok()) { return ::testing::AssertionFailure() - << "Can't get fuction " << expr << " with " << args.size() << " parameters."; + << "Can't get function " << expr << " with " << args.size() << " parameters."; } return ::testing::AssertionSuccess(); } @@ -1489,7 +1489,7 @@ TEST_F(FunctionManagerTest, returnType) { } } -TEST_F(FunctionManagerTest, SchemaReleated) { +TEST_F(FunctionManagerTest, SchemaRelated) { Vertex vertex; Edge edge; diff --git a/src/common/geo/GeoFunction.cpp b/src/common/geo/GeoFunction.cpp index bb058b7b04c..f1340af67bd 100644 --- a/src/common/geo/GeoFunction.cpp +++ b/src/common/geo/GeoFunction.cpp @@ -489,8 +489,8 @@ std::vector GeoFunction::coveringCellIds(const S2Region& r, double GeoFunction::distanceOfS2PolylineWithS2Point(const S2Polyline* aLine, const S2Point& bPoint) { int tmp; - S2Point cloestPointOnLine = aLine->Project(bPoint, &tmp); - return S2Earth::GetDistanceMeters(cloestPointOnLine, bPoint); + S2Point closestPointOnLine = aLine->Project(bPoint, &tmp); + return S2Earth::GetDistanceMeters(closestPointOnLine, bPoint); } double GeoFunction::distanceOfS2PolygonWithS2Polyline(const S2Polygon* aPolygon, diff --git a/src/common/geo/io/wkb/WKBWriter.cpp b/src/common/geo/io/wkb/WKBWriter.cpp index 611ac4bd682..d17572ef154 100644 --- a/src/common/geo/io/wkb/WKBWriter.cpp +++ b/src/common/geo/io/wkb/WKBWriter.cpp @@ -33,7 +33,7 @@ std::string WKBWriter::write(const Geography& geog, ByteOrder byteOrder) { } default: LOG(FATAL) - << "Geomtry shapes other than Point/LineString/Polygon are not currently supported"; + << "Geometry shapes other than Point/LineString/Polygon are not currently supported"; return ""; } } diff --git a/src/common/geo/io/wkt/WKTWriter.cpp b/src/common/geo/io/wkt/WKTWriter.cpp index ec750e566a0..ed925e8a777 100644 --- a/src/common/geo/io/wkt/WKTWriter.cpp +++ b/src/common/geo/io/wkt/WKTWriter.cpp @@ -45,7 +45,7 @@ std::string WKTWriter::write(const Geography& geog) const { } default: LOG(ERROR) - << "Geomtry shapes other than Point/LineString/Polygon are not currently supported"; + << "Geometry shapes other than Point/LineString/Polygon are not currently supported"; return ""; } } diff --git a/src/common/geo/test/CMakeLists.txt b/src/common/geo/test/CMakeLists.txt index a34a1e0f15d..e1455c56154 100644 --- a/src/common/geo/test/CMakeLists.txt +++ b/src/common/geo/test/CMakeLists.txt @@ -14,8 +14,29 @@ nebula_add_test( $ $ $ - $ LIBRARIES gtest gtest_main ) + +nebula_add_test( + NAME + geo_index_test + SOURCES + GeoIndexTest.cpp + OBJECTS + $ + $ + $ + $ + $ + $ + $ + LIBRARIES + ${ROCKSDB_LIBRARIES} + ${THRIFT_LIBRARIES} + ${PROXYGEN_LIBRARIES} + wangle + gtest + gtest_main +) diff --git a/src/common/geo/test/GeoIndexTest.cpp b/src/common/geo/test/GeoIndexTest.cpp new file mode 100644 index 00000000000..fcd377b7770 --- /dev/null +++ b/src/common/geo/test/GeoIndexTest.cpp @@ -0,0 +1,184 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#include + +#include + +#include "common/base/Base.h" +#include "common/geo/GeoIndex.h" + +namespace nebula { +namespace geo { + +std::vector toUint64Vector(std::vector expect) { + auto reinterpretInt64AsUint64 = [](int64_t i) -> uint64_t { + const char* c = reinterpret_cast(&i); + uint64_t u = *reinterpret_cast(c); + return u; + }; + + std::vector transformedExpect; + transformedExpect.reserve(expect.size()); + for (int64_t i : expect) { + transformedExpect.push_back(reinterpretInt64AsUint64(i)); + } + return transformedExpect; +} + +// The tested wkt data is generated by https://clydedacruz.github.io/openstreetmap-wkt-playground/ +TEST(indexCells, point) { + geo::RegionCoverParams rc; + geo::GeoIndex geoIndex(rc); + { + auto point = Geography::fromWKT("POINT(1.0 1.0)").value(); + auto cells = geoIndex.indexCells(point); + EXPECT_EQ(toUint64Vector({1153277837650709461}), cells); + } + { + auto point = Geography::fromWKT("POINT(179.9 -89.999)").value(); + auto cells = geoIndex.indexCells(point); + EXPECT_EQ(toUint64Vector({-5764607523209916331}), cells); + } + { + auto point = Geography::fromWKT("POINT(0.0 0.0)").value(); + auto cells = geoIndex.indexCells(point); + EXPECT_EQ(toUint64Vector({1152921504606846977}), cells); + } + { + auto point = Geography::fromWKT("POINT(-36.843143 79.9999999)").value(); + auto cells = geoIndex.indexCells(point); + EXPECT_EQ(toUint64Vector({5738492864430648919}), cells); + } +} + +TEST(indexCells, lineString) { + geo::RegionCoverParams rc; + geo::GeoIndex geoIndex(rc); + { + auto line = Geography::fromWKT("LINESTRING(1.0 1.0, 2.0 2.0)").value(); + auto cells = geoIndex.indexCells(line); + std::vector expect{ + 1153290940513779712, + 1154047404446580736, + 1154064996699734016, + 1154135365443911680, + 1154164685843464192, + 1154328879221964800, + 1154346471676444672, + }; + EXPECT_EQ(toUint64Vector(expect), cells); + } + { + auto line = Geography::fromWKT( + "LINESTRING(-100.03601074218751 40.74400563300867,-96.96516036987305 " + "39.60634945766583,-91.84398651123048 39.706526341505366)") + .value(); + auto cells = geoIndex.indexCells(line); + std::vector expect{-8676255050873438208, + -8675903207152549888, + -8674214357292285952, + -8665770107990966272, + -8665207158037544960, + -8664644208084123648, + -8664081258130702336, + -8656692539992047616}; + EXPECT_EQ(toUint64Vector(expect), cells); + } + { + auto line = Geography::fromWKT( + "LINESTRING(-109.18024063110352 40.96952973563833,-102.11740493774414 " + "40.98832114106014,-102.00119018554688 37.07120386611709,-108.97098541259767 " + "37.00392356248513,-109.09063339233398 40.94178643285866)") + .value(); + auto cells = geoIndex.indexCells(line); + std::vector expect{-8715591178868752384, + -8714183803985199104, + -8712494954124935168, + -8702080379986640896, + -8699828580172955648, + -8693407432266743808, + -8688569581104529408, + -8686317781290844160}; + EXPECT_EQ(toUint64Vector(expect), cells); + } +} +TEST(indexCells, polygon) { + geo::RegionCoverParams rc; + geo::GeoIndex geoIndex(rc); + { + auto polygon = Geography::fromWKT( + "POLYGON((-105.59286117553711 43.12955341892069,-98.76176834106447 " + "44.11877181138391,-93.97396087646486 " + "38.023348535033705,-105.59286117553711 43.12955341892069))") + .value(); + auto cells = geoIndex.indexCells(polygon); + std::vector expect{-8690821380918214656, + -8686317781290844160, + -8684065981477158912, + -8678436481942945792, + -8665770107990966272, + -8665207158037544960, + -8664644208084123648, + -8662955358223859712}; + EXPECT_EQ(toUint64Vector(expect), cells); + } + { + auto polygon = + Geography::fromWKT( + "POLYGON((-107.24699020385744 45.21638951846552,-91.75283432006836 " + "46.158312926461235,-90.07295608520508 35.17914020576748,-109.77504730224612 " + "38.65334327823746,-107.24699020385744 45.21638951846552))") + .value(); + auto cells = geoIndex.indexCells(polygon); + std::vector expect{5958262307011166208, + 5967269506265907200, + 5994291104030130176, + 6002172403378028544, + -8714465278961909760, + -8702080379986640896, + -8696450880452427776, + -8687443681197686784, + -8678436481942945792, + -8669429282688204800, + -8660422083433463808, + -8651414884178722816}; + EXPECT_EQ(toUint64Vector(expect), cells); + } + { + auto polygon = + Geography::fromWKT( + "POLYGON((-107.17094421386722 51.23698687887105,-100.24475097656253 " + "50.57407993312597,-101.63520812988283 47.57050358015326,-108.1597137451172 " + "47.614032638527846,-107.17094421386722 51.23698687887105),(-106.00682258605956 " + "50.35416859141216,-105.23014068603514 50.212503875989455,-105.55715560913085 " + "49.755319847594194,-106.36962890624999 49.95817799043337,-106.00682258605956 " + "50.35416859141216),(-103.90560150146483 49.21126151433475,-102.1109676361084 " + "49.32232483567492,-102.99759864807127 48.52160729809822,-103.90560150146483 " + "49.21126151433475))") + .value(); + auto cells = geoIndex.indexCells(polygon); + std::vector expect{5969732412312125440, + 5971192563753811968, + 5971491630916567040, + 5972899005800120320, + 5986409804682231808, + 5988661604495917056, + 5990913404309602304, + 5997668803750658048}; + EXPECT_EQ(toUint64Vector(expect), cells); + } +} + +} // namespace geo +} // namespace nebula + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + folly::init(&argc, &argv, true); + google::SetStderrLogging(google::INFO); + + return RUN_ALL_TESTS(); +} diff --git a/src/common/graph/Response.h b/src/common/graph/Response.h index 727c974f68b..51ad260240d 100644 --- a/src/common/graph/Response.h +++ b/src/common/graph/Response.h @@ -82,7 +82,7 @@ X(E_BALANCED, -2024) \ X(E_NO_RUNNING_BALANCE_PLAN, -2025) \ X(E_NO_VALID_HOST, -2026) \ - X(E_CORRUPTTED_BALANCE_PLAN, -2027) \ + X(E_CORRUPTED_BALANCE_PLAN, -2027) \ X(E_NO_INVALID_BALANCE_PLAN, -2028) \ \ /* Authentication Failure */ \ diff --git a/src/common/graph/tests/ResponseEncodeDecodeTest.cpp b/src/common/graph/tests/ResponseEncodeDecodeTest.cpp index a741f57dd3b..de61bc32de8 100644 --- a/src/common/graph/tests/ResponseEncodeDecodeTest.cpp +++ b/src/common/graph/tests/ResponseEncodeDecodeTest.cpp @@ -15,7 +15,7 @@ namespace nebula { using serializer = apache::thrift::CompactSerializer; -TEST(ResponseEncodDecodeTest, Basic) { +TEST(ResponseEncodeDecodeTest, Basic) { // auth response { std::vector resps; @@ -88,7 +88,7 @@ TEST(ResponseEncodDecodeTest, Basic) { } } -TEST(ResponseEncodDecodeTest, ToJson) { +TEST(ResponseEncodeDecodeTest, ToJson) { // plan description { std::vector pds; diff --git a/src/common/meta/GflagsManager.cpp b/src/common/meta/GflagsManager.cpp index 56731c28e57..a7dd8289981 100644 --- a/src/common/meta/GflagsManager.cpp +++ b/src/common/meta/GflagsManager.cpp @@ -54,7 +54,7 @@ std::unordered_map> GflagsManager {"v", {cpp2::ConfigMode::MUTABLE, false}}, {"heartbeat_interval_secs", {cpp2::ConfigMode::MUTABLE, false}}, {"meta_client_retry_times", {cpp2::ConfigMode::MUTABLE, false}}, - {"slow_op_threshhold_ms", {cpp2::ConfigMode::MUTABLE, false}}, + {"slow_op_threshold_ms", {cpp2::ConfigMode::MUTABLE, false}}, {"wal_ttl", {cpp2::ConfigMode::MUTABLE, false}}, {"clean_wal_interval_secs", {cpp2::ConfigMode::MUTABLE, false}}, {"custom_filter_interval_secs", {cpp2::ConfigMode::MUTABLE, false}}, diff --git a/src/common/network/NetworkUtils.cpp b/src/common/network/NetworkUtils.cpp index 14d3323610e..b0571c0e240 100644 --- a/src/common/network/NetworkUtils.cpp +++ b/src/common/network/NetworkUtils.cpp @@ -88,7 +88,7 @@ bool NetworkUtils::getDynamicPortRange(uint16_t& low, uint16_t& high) { if (fscanf(pipe, "%hu %hu", &low, &high) != 2) { LOG(ERROR) << "Failed to read from /proc/sys/net/ipv4/ip_local_port_range"; - // According to ICANN, the port range is devided into three sections + // According to ICANN, the port range is divided into three sections // // Well-known ports: 0 to 1023 (used for system services) // Registered/user ports: 1024 to 49151 @@ -171,7 +171,7 @@ uint16_t NetworkUtils::getAvailablePort() { uint16_t port = 0; while (true) { // NOTE - // The availablity of port number *outside* the ephemeral port range is + // The availability of port number *outside* the ephemeral port range is // relatively stable for the binding purpose. port = folly::Random::rand32(1025, low); if (portsInUse.find(port) != portsInUse.end()) { diff --git a/src/common/network/NetworkUtils.h b/src/common/network/NetworkUtils.h index 8062397c898..be95b1580e8 100644 --- a/src/common/network/NetworkUtils.h +++ b/src/common/network/NetworkUtils.h @@ -24,7 +24,7 @@ class NetworkUtils final { static StatusOr getIPv4FromDevice(const std::string& device); // List out all Ipv4 addresses, including the loopback one. static StatusOr> listIPv4s(); - // List out all network devices and its cooresponding Ipv4 address. + // List out all network devices and its corresponding Ipv4 address. static StatusOr> listDeviceAndIPv4s(); // Get the local dynamic port range [low, high], only works for IPv4 diff --git a/src/common/network/test/NetworkUtilsTest.cpp b/src/common/network/test/NetworkUtilsTest.cpp index 3092c255909..21d38e27101 100644 --- a/src/common/network/test/NetworkUtilsTest.cpp +++ b/src/common/network/test/NetworkUtilsTest.cpp @@ -34,7 +34,7 @@ TEST(NetworkUtils, getIPv4FromDevice) { ASSERT_EQ("0.0.0.0", result.value()); } { - auto result = NetworkUtils::getIPv4FromDevice("non-existence"); + auto result = NetworkUtils::getIPv4FromDevice("nonexistent"); ASSERT_FALSE(result.ok()) << result.status(); } } diff --git a/src/common/plugin/fulltext/test/FulltextPluginTest.cpp b/src/common/plugin/fulltext/test/FulltextPluginTest.cpp index ce8f85c1ce8..c79550da633 100644 --- a/src/common/plugin/fulltext/test/FulltextPluginTest.cpp +++ b/src/common/plugin/fulltext/test/FulltextPluginTest.cpp @@ -100,18 +100,18 @@ TEST(FulltextPluginTest, ESBulkTest) { "charset=utf-8\" -XPOST \"http://127.0.0.1:9200/_bulk\""; ASSERT_EQ(expected, header); - std::vector bodys; + std::vector bodies; for (const auto& item : items) { folly::dynamic meta = folly::dynamic::object("_id", DocIDTraits::docId(item))("_index", item.index); folly::dynamic data = folly::dynamic::object("value", DocIDTraits::val(item.val))( "column_id", DocIDTraits::column(item.column)); - bodys.emplace_back(folly::dynamic::object("index", std::move(meta))); - bodys.emplace_back(std::move(data)); + bodies.emplace_back(folly::dynamic::object("index", std::move(meta))); + bodies.emplace_back(std::move(data)); } auto body = ESStorageAdapter().bulkBody(items); - verifyBodyStr(body, std::move(bodys)); + verifyBodyStr(body, std::move(bodies)); } TEST(FulltextPluginTest, ESPutToTest) { @@ -216,13 +216,13 @@ TEST(FulltextPluginTest, ESResultTest) { // "root_cause": [ // { // "type": "parsing_exception", - // "reason": "Unknown key for a VALUE_STRING in [_soure].", + // "reason": "Unknown key for a VALUE_STRING in [_source].", // "line": 1, // "col": 128 // } // ], // "type": "parsing_exception", - // "reason": "Unknown key for a VALUE_STRING in [_soure].", + // "reason": "Unknown key for a VALUE_STRING in [_source].", // "line": 1, // "col": 128 // }, @@ -231,9 +231,9 @@ TEST(FulltextPluginTest, ESResultTest) { { std::string json = R"({"error": {"root_cause": [{"type": "parsing_exception","reason": - "Unknown key for a VALUE_STRING in [_soure].","line": 1,"col": 128}], + "Unknown key for a VALUE_STRING in [_source].","line": 1,"col": 128}], "type": "parsing_exception","reason": "Unknown key for a VALUE_STRING - in [_soure].","line": 1,"col": 128},"status": 400})"; + in [_source].","line": 1,"col": 128},"status": 400})"; HostAddr localHost_{"127.0.0.1", 9200}; HttpClient hc(localHost_); std::vector rows; diff --git a/src/common/process/ProcessUtils.cpp b/src/common/process/ProcessUtils.cpp index 0b73c306e8c..d33851131fa 100644 --- a/src/common/process/ProcessUtils.cpp +++ b/src/common/process/ProcessUtils.cpp @@ -26,7 +26,7 @@ Status ProcessUtils::isPidAvailable(pid_t pid) { return Status::Error("Process `%d' already existed but denied to access", pid); } if (errno != ESRCH) { - return Status::Error("Uknown error: `%s'", ::strerror(errno)); + return Status::Error("Unknown error: `%s'", ::strerror(errno)); } return Status::OK(); } diff --git a/src/common/stats/StatsManager.cpp b/src/common/stats/StatsManager.cpp index dc6a604c944..083b7c890db 100644 --- a/src/common/stats/StatsManager.cpp +++ b/src/common/stats/StatsManager.cpp @@ -163,12 +163,12 @@ void StatsManager::addValue(const CounterId& id, VT value) { // static bool StatsManager::strToPct(folly::StringPiece part, double& pct) { - static const int32_t dividors[] = {1, 1, 10, 100, 1000, 10000}; + static const int32_t divisors[] = {1, 1, 10, 100, 1000, 10000}; try { size_t len = part.size() - 1; if (len > 0 && len <= 6) { auto digits = folly::StringPiece(&(part[1]), len); - pct = folly::to(digits) / dividors[len - 1]; + pct = folly::to(digits) / divisors[len - 1]; return true; } else { LOG(ERROR) << "Precision " << part.toString() << " is too long"; diff --git a/src/common/stats/StatsManager.h b/src/common/stats/StatsManager.h index 5c4fe4960f6..3a1524c088a 100644 --- a/src/common/stats/StatsManager.h +++ b/src/common/stats/StatsManager.h @@ -61,7 +61,7 @@ class CounterId final { * This is a utility class to keep track the service's statistic information. * * It contains a bunch of counters. Each counter has a unique name and three - * levels of time ranges, which are 1 minute, 10 minues, and 1 hour. Each + * levels of time ranges, which are 1 minute, 10 minutes, and 1 hour. Each * counter also associates with one or multiple statistic types. The supported * statistic types are SUM, COUNT, AVG, RATE, MIN, MAX and percentiles. Among * those, MIN, MAX and Percentile are only supported for Histogram counters. diff --git a/src/common/thread/GenericThreadPool.h b/src/common/thread/GenericThreadPool.h index 63e8e6a07dd..fc2bdd87ccf 100644 --- a/src/common/thread/GenericThreadPool.h +++ b/src/common/thread/GenericThreadPool.h @@ -44,7 +44,7 @@ class GenericThreadPool final : public nebula::cpp::NonCopyable, public nebula:: bool start(size_t nrThreads, const std::string &name = ""); /** - * Asynchronouly to notify the workers to stop handling further new tasks. + * Asynchronously to notify the workers to stop handling further new tasks. */ bool stop(); diff --git a/src/common/thread/GenericWorker.cpp b/src/common/thread/GenericWorker.cpp index c21c442c8db..b80076450fb 100644 --- a/src/common/thread/GenericWorker.cpp +++ b/src/common/thread/GenericWorker.cpp @@ -142,10 +142,10 @@ void GenericWorker::onNotify() { } } { - decltype(purgingingTimers_) newcomings; + decltype(purgingTimers_) newcomings; { std::lock_guard guard(lock_); - newcomings.swap(purgingingTimers_); + newcomings.swap(purgingTimers_); } for (auto id : newcomings) { purgeTimerInternal(id); @@ -164,7 +164,7 @@ GenericWorker::Timer::~Timer() { void GenericWorker::purgeTimerTask(uint64_t id) { { std::lock_guard guard(lock_); - purgingingTimers_.emplace_back(id); + purgingTimers_.emplace_back(id); } notify(); } diff --git a/src/common/thread/GenericWorker.h b/src/common/thread/GenericWorker.h index fe07592bb1f..80999197b12 100644 --- a/src/common/thread/GenericWorker.h +++ b/src/common/thread/GenericWorker.h @@ -39,7 +39,7 @@ class GenericWorker final : public nebula::cpp::NonCopyable, public nebula::cpp: ~GenericWorker(); /** - * To allocate resouces and launch the internal thread which executes + * To allocate resources and launch the internal thread which executes * the event loop to make this worker usable. * * Optionally, you could give the internal thread a specific name, @@ -54,7 +54,7 @@ class GenericWorker final : public nebula::cpp::NonCopyable, public nebula::cpp: bool NG_MUST_USE_RESULT start(std::string name = ""); /** - * Asynchronouly to notify the worker to stop handling further new tasks. + * Asynchronously to notify the worker to stop handling further new tasks. */ bool stop(); @@ -160,7 +160,7 @@ class GenericWorker final : public nebula::cpp::NonCopyable, public nebula::cpp: std::vector> pendingTasks_; using TimerPtr = std::unique_ptr; std::vector pendingTimers_; - std::vector purgingingTimers_; + std::vector purgingTimers_; std::unordered_map activeTimers_; std::unique_ptr thread_; }; diff --git a/src/common/time/TimeConversion.h b/src/common/time/TimeConversion.h index a5950e1bafc..aeaaab5de01 100644 --- a/src/common/time/TimeConversion.h +++ b/src/common/time/TimeConversion.h @@ -109,7 +109,7 @@ class TimeConversion { // https://en.cppreference.com/w/cpp/language/operator_arithmetic). So make // sure the result is what we expected, if right shift not filled highest bit // by the sign bit that the process will falls back to procedure which fill - // hightest bit by the sign bit value. + // highest bit by the sign bit value. static int64_t shr(int64_t a, int b) { int64_t one = 1; return (-one >> 1 == -1 ? a >> b : (a + (a < 0)) / (one << b) - (a < 0)); diff --git a/src/common/time/TimeUtils.cpp b/src/common/time/TimeUtils.cpp index bcc6773032c..e9e65fb6361 100644 --- a/src/common/time/TimeUtils.cpp +++ b/src/common/time/TimeUtils.cpp @@ -65,7 +65,7 @@ constexpr int64_t kMaxTimestamp = std::numeric_limits::max() / 10000000 } dt.microsec += kv.second.getInt(); } else { - return Status::Error("Invlaid parameter `%s'.", kv.first.c_str()); + return Status::Error("Invalid parameter `%s'.", kv.first.c_str()); } } auto result = validateDate(dt); @@ -98,7 +98,7 @@ constexpr int64_t kMaxTimestamp = std::numeric_limits::max() / 10000000 } d.day = kv.second.getInt(); } else { - return Status::Error("Invlaid parameter `%s'.", kv.first.c_str()); + return Status::Error("Invalid parameter `%s'.", kv.first.c_str()); } } auto result = validateDate(d); @@ -140,7 +140,7 @@ constexpr int64_t kMaxTimestamp = std::numeric_limits::max() / 10000000 } t.microsec += kv.second.getInt(); } else { - return Status::Error("Invlaid parameter `%s'.", kv.first.c_str()); + return Status::Error("Invalid parameter `%s'.", kv.first.c_str()); } } return t; diff --git a/src/common/time/TimeUtils.h b/src/common/time/TimeUtils.h index 12235e0851e..2c409817391 100644 --- a/src/common/time/TimeUtils.h +++ b/src/common/time/TimeUtils.h @@ -25,7 +25,7 @@ namespace nebula { namespace time { -// In nebula only store UTC time, and the interpretion of time value based on +// In nebula only store UTC time, and the interpretation of time value based on // the timezone configuration in current system. class TimeUtils { diff --git a/src/common/time/test/TimeUtilsTest.cpp b/src/common/time/test/TimeUtilsTest.cpp index 60c2d53e44b..d0cc1edf7be 100644 --- a/src/common/time/test/TimeUtilsTest.cpp +++ b/src/common/time/test/TimeUtilsTest.cpp @@ -11,7 +11,7 @@ namespace nebula { -TEST(Time, secondsTimeCovertion) { +TEST(Time, secondsTimeConversion) { // DateTime { std::vector values; diff --git a/src/common/utils/CMakeLists.txt b/src/common/utils/CMakeLists.txt index f240cb25f5b..1c909fbc0b2 100644 --- a/src/common/utils/CMakeLists.txt +++ b/src/common/utils/CMakeLists.txt @@ -12,5 +12,10 @@ nebula_add_library( MetaKeyUtils.cpp ) +nebula_add_library( + log_str_list_iterator_obj OBJECT + LogStrListIterator.cpp +) + nebula_add_subdirectory(test) diff --git a/src/common/utils/IndexKeyUtils.h b/src/common/utils/IndexKeyUtils.h index 1e5f6349509..c8bdd4fb967 100644 --- a/src/common/utils/IndexKeyUtils.h +++ b/src/common/utils/IndexKeyUtils.h @@ -457,7 +457,7 @@ class IndexKeyUtils final { } static VertexIDSlice getIndexVertexID(size_t vIdLen, const folly::StringPiece& rawKey) { - CHECK_GE(rawKey.size(), kVertexIndexLen + vIdLen); + CHECK_GE(rawKey.size(), kTagIndexLen + vIdLen); auto offset = rawKey.size() - vIdLen; return rawKey.subpiece(offset, vIdLen); } diff --git a/src/kvstore/raftex/LogStrListIterator.cpp b/src/common/utils/LogStrListIterator.cpp similarity index 92% rename from src/kvstore/raftex/LogStrListIterator.cpp rename to src/common/utils/LogStrListIterator.cpp index dfcd452ca17..d33a0ffd0eb 100644 --- a/src/kvstore/raftex/LogStrListIterator.cpp +++ b/src/common/utils/LogStrListIterator.cpp @@ -3,13 +3,12 @@ * This source code is licensed under Apache 2.0 License. */ -#include "kvstore/raftex/LogStrListIterator.h" +#include "common/utils/LogStrListIterator.h" #include "common/base/Base.h" #include "common/thrift/ThriftTypes.h" namespace nebula { -namespace raftex { LogStrListIterator::LogStrListIterator(LogID firstLogId, TermID term, @@ -45,5 +44,4 @@ folly::StringPiece LogStrListIterator::logMsg() const { return logEntries_.at(idx_).get_log_str(); } -} // namespace raftex } // namespace nebula diff --git a/src/kvstore/raftex/LogStrListIterator.h b/src/common/utils/LogStrListIterator.h similarity index 78% rename from src/kvstore/raftex/LogStrListIterator.h rename to src/common/utils/LogStrListIterator.h index f1be123538d..2e724711f6e 100644 --- a/src/kvstore/raftex/LogStrListIterator.h +++ b/src/common/utils/LogStrListIterator.h @@ -3,15 +3,14 @@ * This source code is licensed under Apache 2.0 License. */ -#ifndef RAFTEX_LOGSTRLISTITERATOR_H_ -#define RAFTEX_LOGSTRLISTITERATOR_H_ +#ifndef COMMON_UTILS_LOGSTRLISTITERATOR_H_ +#define COMMON_UTILS_LOGSTRLISTITERATOR_H_ #include "common/base/Base.h" #include "common/utils/LogIterator.h" -#include "interface/gen-cpp2/raftex_types.h" +#include "interface/gen-cpp2/common_types.h" namespace nebula { -namespace raftex { class LogStrListIterator final : public LogIterator { public: @@ -33,7 +32,6 @@ class LogStrListIterator final : public LogIterator { std::vector logEntries_; }; -} // namespace raftex } // namespace nebula -#endif // RAFTEX_LOGSTRLISTITERATOR_H_ +#endif // COMMON_UTILS_LOGSTRLISTITERATOR_H_ diff --git a/src/common/utils/MemoryLockWrapper.h b/src/common/utils/MemoryLockWrapper.h index 8e5f73ecca4..7fff4f6bf32 100644 --- a/src/common/utils/MemoryLockWrapper.h +++ b/src/common/utils/MemoryLockWrapper.h @@ -68,7 +68,7 @@ class MemoryLockGuard { } // this will manual set the lock to unlocked state - // which mean will not release all locks automaticly + // which mean will not release all locks automatically // please make sure you really know the side effect void forceLock() { locked_ = true; } diff --git a/src/common/utils/MetaKeyUtils.cpp b/src/common/utils/MetaKeyUtils.cpp index 92dfa0ea400..3018051273d 100644 --- a/src/common/utils/MetaKeyUtils.cpp +++ b/src/common/utils/MetaKeyUtils.cpp @@ -27,7 +27,7 @@ static const std::unordered_map> syste {"ft_service", {"__ft_service__", false}}, {"sessions", {"__sessions__", true}}}; -// SystemInfo will always be backuped +// SystemInfo will always be backed up static const std::unordered_map> systemInfoMaps{ {"autoIncrementId", {"__id__", true}}, {"lastUpdateTime", {"__last_update_time__", true}}}; @@ -206,7 +206,7 @@ std::vector MetaKeyUtils::parsePartVal(folly::StringPiece val, int par return parsePartValV2(val); } -// partion val is ip(int) + port(int) +// partition val is ip(int) + port(int) std::vector MetaKeyUtils::parsePartValV1(folly::StringPiece val) { std::vector hosts; static const size_t unitSize = sizeof(int32_t) * 2; @@ -889,13 +889,13 @@ std::string MetaKeyUtils::balanceTaskKey( } std::string MetaKeyUtils::balanceTaskVal(BalanceTaskStatus status, - BalanceTaskResult retult, + BalanceTaskResult result, int64_t startTime, int64_t endTime) { std::string val; val.reserve(32); val.append(reinterpret_cast(&status), sizeof(BalanceTaskStatus)) - .append(reinterpret_cast(&retult), sizeof(BalanceTaskResult)) + .append(reinterpret_cast(&result), sizeof(BalanceTaskResult)) .append(reinterpret_cast(&startTime), sizeof(int64_t)) .append(reinterpret_cast(&endTime), sizeof(int64_t)); return val; diff --git a/src/common/utils/MetaKeyUtils.h b/src/common/utils/MetaKeyUtils.h index 49e5b794df1..e01eb2d67fc 100644 --- a/src/common/utils/MetaKeyUtils.h +++ b/src/common/utils/MetaKeyUtils.h @@ -268,7 +268,7 @@ class MetaKeyUtils final { JobID jobId, GraphSpaceID spaceId, PartitionID partId, HostAddr src, HostAddr dst); static std::string balanceTaskVal(BalanceTaskStatus status, - BalanceTaskResult retult, + BalanceTaskResult result, int64_t startTime, int64_t endTime); diff --git a/src/common/utils/NebulaKeyUtils.cpp b/src/common/utils/NebulaKeyUtils.cpp index 6445d8e88dd..9e7cc2585f7 100644 --- a/src/common/utils/NebulaKeyUtils.cpp +++ b/src/common/utils/NebulaKeyUtils.cpp @@ -34,13 +34,13 @@ std::string NebulaKeyUtils::lastKey(const std::string& prefix, size_t count) { } // static -std::string NebulaKeyUtils::vertexKey( +std::string NebulaKeyUtils::tagKey( size_t vIdLen, PartitionID partId, const VertexID& vId, TagID tagId, char pad) { CHECK_GE(vIdLen, vId.size()); - int32_t item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kVertex); + int32_t item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kTag_); std::string key; - key.reserve(kVertexLen + vIdLen); + key.reserve(kTagLen + vIdLen); key.append(reinterpret_cast(&item), sizeof(int32_t)) .append(vId.data(), vId.size()) .append(vIdLen - vId.size(), pad) @@ -106,12 +106,12 @@ std::string NebulaKeyUtils::kvKey(PartitionID partId, const folly::StringPiece& } // static -std::string NebulaKeyUtils::vertexPrefix(size_t vIdLen, - PartitionID partId, - const VertexID& vId, - TagID tagId) { +std::string NebulaKeyUtils::tagPrefix(size_t vIdLen, + PartitionID partId, + const VertexID& vId, + TagID tagId) { CHECK_GE(vIdLen, vId.size()); - PartitionID item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kVertex); + PartitionID item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kTag_); std::string key; key.reserve(sizeof(PartitionID) + vIdLen + sizeof(TagID)); @@ -123,9 +123,9 @@ std::string NebulaKeyUtils::vertexPrefix(size_t vIdLen, } // static -std::string NebulaKeyUtils::vertexPrefix(size_t vIdLen, PartitionID partId, const VertexID& vId) { +std::string NebulaKeyUtils::tagPrefix(size_t vIdLen, PartitionID partId, const VertexID& vId) { CHECK_GE(vIdLen, vId.size()); - PartitionID item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kVertex); + PartitionID item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kTag_); std::string key; key.reserve(sizeof(PartitionID) + vIdLen); key.append(reinterpret_cast(&item), sizeof(PartitionID)) @@ -135,8 +135,8 @@ std::string NebulaKeyUtils::vertexPrefix(size_t vIdLen, PartitionID partId, cons } // static -std::string NebulaKeyUtils::vertexPrefix(PartitionID partId) { - PartitionID item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kVertex); +std::string NebulaKeyUtils::tagPrefix(PartitionID partId) { + PartitionID item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kTag_); std::string key; key.reserve(sizeof(PartitionID)); key.append(reinterpret_cast(&item), sizeof(PartitionID)); @@ -210,7 +210,7 @@ std::vector NebulaKeyUtils::snapshotPrefix(PartitionID partId) { if (partId == 0) { result.emplace_back(""); } else { - result.emplace_back(vertexPrefix(partId)); + result.emplace_back(tagPrefix(partId)); result.emplace_back(edgePrefix(partId)); result.emplace_back(IndexKeyUtils::indexPrefix(partId)); // kSystem will be written when balance data diff --git a/src/common/utils/NebulaKeyUtils.h b/src/common/utils/NebulaKeyUtils.h index 5dc5904c2bf..0d0ba17ea24 100644 --- a/src/common/utils/NebulaKeyUtils.h +++ b/src/common/utils/NebulaKeyUtils.h @@ -11,7 +11,7 @@ namespace nebula { /** - * VertexKeyUtils: + * TagKeyUtils: * type(1) + partId(3) + vertexId(*) + tagId(4) * * EdgeKeyUtils: @@ -55,7 +55,7 @@ class NebulaKeyUtils final { /** * Generate vertex key for kv store * */ - static std::string vertexKey( + static std::string tagKey( size_t vIdLen, PartitionID partId, const VertexID& vId, TagID tagId, char pad = '\0'); static std::string edgeKey(size_t vIdLen, @@ -75,14 +75,11 @@ class NebulaKeyUtils final { /** * Prefix for vertex * */ - static std::string vertexPrefix(size_t vIdLen, - PartitionID partId, - const VertexID& vId, - TagID tagId); + static std::string tagPrefix(size_t vIdLen, PartitionID partId, const VertexID& vId, TagID tagId); - static std::string vertexPrefix(size_t vIdLen, PartitionID partId, const VertexID& vId); + static std::string tagPrefix(size_t vIdLen, PartitionID partId, const VertexID& vId); - static std::string vertexPrefix(PartitionID partId); + static std::string tagPrefix(PartitionID partId); /** * Prefix for edge @@ -111,26 +108,26 @@ class NebulaKeyUtils final { return readInt(rawKey.data(), sizeof(PartitionID)) >> 8; } - static bool isVertex(size_t vIdLen, const folly::StringPiece& rawKey) { - if (rawKey.size() != kVertexLen + vIdLen) { + static bool isTag(size_t vIdLen, const folly::StringPiece& rawKey) { + if (rawKey.size() != kTagLen + vIdLen) { return false; } constexpr int32_t len = static_cast(sizeof(NebulaKeyType)); auto type = readInt(rawKey.data(), len) & kTypeMask; - return static_cast(type) == NebulaKeyType::kVertex; + return static_cast(type) == NebulaKeyType::kTag_; } static VertexIDSlice getVertexId(size_t vIdLen, const folly::StringPiece& rawKey) { - if (rawKey.size() != kVertexLen + vIdLen) { - dumpBadKey(rawKey, kVertexLen + vIdLen, vIdLen); + if (rawKey.size() != kTagLen + vIdLen) { + dumpBadKey(rawKey, kTagLen + vIdLen, vIdLen); } auto offset = sizeof(PartitionID); return rawKey.subpiece(offset, vIdLen); } static TagID getTagId(size_t vIdLen, const folly::StringPiece& rawKey) { - if (rawKey.size() != kVertexLen + vIdLen) { - dumpBadKey(rawKey, kVertexLen + vIdLen, vIdLen); + if (rawKey.size() != kTagLen + vIdLen) { + dumpBadKey(rawKey, kTagLen + vIdLen, vIdLen); } auto offset = sizeof(PartitionID) + vIdLen; return readInt(rawKey.data() + offset, sizeof(TagID)); @@ -233,7 +230,7 @@ class NebulaKeyUtils final { } static folly::StringPiece keyWithNoVersion(const folly::StringPiece& rawKey) { - // TODO(heng) We should change the method if varint data version supportted. + // TODO(heng) We should change the method if varint data version supported. return rawKey.subpiece(0, rawKey.size() - sizeof(EdgeVerPlaceHolder)); } @@ -255,7 +252,7 @@ class NebulaKeyUtils final { static folly::StringPiece lockWithNoVersion(const folly::StringPiece& rawKey) { // TODO(liuyu) We should change the method if varint data version - // supportted. + // supported. return rawKey.subpiece(0, rawKey.size() - 1); } diff --git a/src/common/utils/Types.h b/src/common/utils/Types.h index 1546cd537ee..8012ac91305 100644 --- a/src/common/utils/Types.h +++ b/src/common/utils/Types.h @@ -12,12 +12,13 @@ namespace nebula { enum class NebulaKeyType : uint32_t { - kVertex = 0x00000001, + kTag_ = 0x00000001, kEdge = 0x00000002, kIndex = 0x00000003, kSystem = 0x00000004, kOperation = 0x00000005, kKeyValue = 0x00000006, + // kVertex = 0x00000007, }; enum class NebulaSystemKeyType : uint32_t { @@ -41,7 +42,7 @@ static typename std::enable_if::value, T>::type readInt(cons } // size of vertex key except vertexId -static constexpr int32_t kVertexLen = sizeof(PartitionID) + sizeof(TagID); +static constexpr int32_t kTagLen = sizeof(PartitionID) + sizeof(TagID); // size of vertex key except srcId and dstId static constexpr int32_t kEdgeLen = @@ -56,7 +57,7 @@ static constexpr uint8_t kPartitionOffset = 8; // See KeyType enum static constexpr uint32_t kTypeMask = 0x000000FF; -static constexpr int32_t kVertexIndexLen = sizeof(PartitionID) + sizeof(IndexID); +static constexpr int32_t kTagIndexLen = sizeof(PartitionID) + sizeof(IndexID); static constexpr int32_t kEdgeIndexLen = sizeof(PartitionID) + sizeof(IndexID) + sizeof(EdgeRanking); diff --git a/src/common/utils/test/NebulaKeyUtilsTest.cpp b/src/common/utils/test/NebulaKeyUtilsTest.cpp index eb5504225b2..206d756daab 100644 --- a/src/common/utils/test/NebulaKeyUtilsTest.cpp +++ b/src/common/utils/test/NebulaKeyUtilsTest.cpp @@ -16,18 +16,18 @@ class KeyUtilsTestBase : public ::testing::Test { ~KeyUtilsTestBase() = default; - void verifyVertex(PartitionID partId, VertexID vId, TagID tagId, size_t actualSize) { - auto vertexKey = NebulaKeyUtils::vertexKey(vIdLen_, partId, vId, tagId); - ASSERT_EQ(vertexKey.size(), kVertexLen + vIdLen_); - ASSERT_EQ(vertexKey.substr(0, sizeof(PartitionID) + vIdLen_ + sizeof(TagID)), - NebulaKeyUtils::vertexPrefix(vIdLen_, partId, vId, tagId)); - ASSERT_EQ(vertexKey.substr(0, sizeof(PartitionID) + vIdLen_), - NebulaKeyUtils::vertexPrefix(vIdLen_, partId, vId)); - ASSERT_TRUE(NebulaKeyUtils::isVertex(vIdLen_, vertexKey)); - ASSERT_FALSE(NebulaKeyUtils::isEdge(vIdLen_, vertexKey)); - ASSERT_EQ(partId, NebulaKeyUtils::getPart(vertexKey)); - ASSERT_EQ(tagId, NebulaKeyUtils::getTagId(vIdLen_, vertexKey)); - ASSERT_EQ(vId, NebulaKeyUtils::getVertexId(vIdLen_, vertexKey).subpiece(0, actualSize)); + void verifyTag(PartitionID partId, VertexID vId, TagID tagId, size_t actualSize) { + auto tagKey = NebulaKeyUtils::tagKey(vIdLen_, partId, vId, tagId); + ASSERT_EQ(tagKey.size(), kTagLen + vIdLen_); + ASSERT_EQ(tagKey.substr(0, sizeof(PartitionID) + vIdLen_ + sizeof(TagID)), + NebulaKeyUtils::tagPrefix(vIdLen_, partId, vId, tagId)); + ASSERT_EQ(tagKey.substr(0, sizeof(PartitionID) + vIdLen_), + NebulaKeyUtils::tagPrefix(vIdLen_, partId, vId)); + ASSERT_TRUE(NebulaKeyUtils::isTag(vIdLen_, tagKey)); + ASSERT_FALSE(NebulaKeyUtils::isEdge(vIdLen_, tagKey)); + ASSERT_EQ(partId, NebulaKeyUtils::getPart(tagKey)); + ASSERT_EQ(tagId, NebulaKeyUtils::getTagId(vIdLen_, tagKey)); + ASSERT_EQ(vId, NebulaKeyUtils::getVertexId(vIdLen_, tagKey).subpiece(0, actualSize)); } void verifyEdge(PartitionID partId, @@ -47,7 +47,7 @@ class KeyUtilsTestBase : public ::testing::Test { 0, sizeof(PartitionID) + (vIdLen_ << 1) + sizeof(EdgeType) + sizeof(EdgeRanking)), NebulaKeyUtils::edgePrefix(vIdLen_, partId, srcId, type, rank, dstId)); ASSERT_TRUE(NebulaKeyUtils::isEdge(vIdLen_, edgeKey)); - ASSERT_FALSE(NebulaKeyUtils::isVertex(vIdLen_, edgeKey)); + ASSERT_FALSE(NebulaKeyUtils::isTag(vIdLen_, edgeKey)); ASSERT_EQ(partId, NebulaKeyUtils::getPart(edgeKey)); ASSERT_EQ(srcId, NebulaKeyUtils::getSrcId(vIdLen_, edgeKey).subpiece(0, actualSize)); ASSERT_EQ(dstId, NebulaKeyUtils::getDstId(vIdLen_, edgeKey).subpiece(0, actualSize)); @@ -85,7 +85,7 @@ TEST_F(V1Test, SimpleTest) { VertexID vId = getStringId(1001L); TagID tagId = 2020; TagVersion tagVersion = folly::Random::rand64(); - verifyVertex(partId, vId, tagId, tagVersion); + verifyTag(partId, vId, tagId, tagVersion); VertexID srcId = getStringId(1001L), dstId = getStringId(2001L); EdgeType type = 1010; @@ -98,7 +98,7 @@ TEST_F(V1Test, NegativeEdgeTypeTest) { PartitionID partId = 123; VertexID vId = getStringId(1001L); TagID tagId = 2020; - verifyVertex(partId, vId, tagId, sizeof(int64_t)); + verifyTag(partId, vId, tagId, sizeof(int64_t)); VertexID srcId = getStringId(1001L), dstId = getStringId(2001L); EdgeType type = -1010; @@ -111,7 +111,7 @@ TEST_F(V2ShortTest, SimpleTest) { PartitionID partId = 123; VertexID vId = "0123456789"; TagID tagId = 2020; - verifyVertex(partId, vId, tagId, 10); + verifyTag(partId, vId, tagId, 10); VertexID srcId = "0123456789", dstId = "9876543210"; EdgeType type = 1010; @@ -124,7 +124,7 @@ TEST_F(V2ShortTest, NegativeEdgeTypeTest) { PartitionID partId = 123; VertexID vId = "0123456789"; TagID tagId = 2020; - verifyVertex(partId, vId, tagId, 10); + verifyTag(partId, vId, tagId, 10); VertexID srcId = "0123456789", dstId = "9876543210"; EdgeType type = -1010; @@ -137,7 +137,7 @@ TEST_F(V2LongTest, SimpleTest) { PartitionID partId = 123; VertexID vId = "0123456789"; TagID tagId = 2020; - verifyVertex(partId, vId, tagId, 10); + verifyTag(partId, vId, tagId, 10); VertexID srcId = "0123456789", dstId = "9876543210"; EdgeType type = 1010; @@ -150,7 +150,7 @@ TEST_F(V2LongTest, NegativeEdgeTypeTest) { PartitionID partId = 123; VertexID vId = "0123456789"; TagID tagId = 2020; - verifyVertex(partId, vId, tagId, 10); + verifyTag(partId, vId, tagId, 10); VertexID srcId = "0123456789", dstId = "9876543210"; EdgeType type = -1010; diff --git a/src/daemons/CMakeLists.txt b/src/daemons/CMakeLists.txt index 0fcbcbcd8d0..1a92710dc34 100644 --- a/src/daemons/CMakeLists.txt +++ b/src/daemons/CMakeLists.txt @@ -42,6 +42,7 @@ set(storage_meta_deps $ $ $ + $ $ $ $ diff --git a/src/daemons/MetaDaemon.cpp b/src/daemons/MetaDaemon.cpp index 2a95ded57f9..e1df6369c29 100644 --- a/src/daemons/MetaDaemon.cpp +++ b/src/daemons/MetaDaemon.cpp @@ -328,7 +328,7 @@ int main(int argc, char* argv[]) { } auto handler = std::make_shared(gKVStore.get(), gClusterId); - LOG(INFO) << "The meta deamon start on " << localhost; + LOG(INFO) << "The meta daemon start on " << localhost; try { gServer = std::make_unique(); gServer->setPort(FLAGS_port); diff --git a/src/graph/context/ExecutionContext.cpp b/src/graph/context/ExecutionContext.cpp index b1fcc17fb49..dbb064c01af 100644 --- a/src/graph/context/ExecutionContext.cpp +++ b/src/graph/context/ExecutionContext.cpp @@ -30,7 +30,7 @@ size_t ExecutionContext::numVersions(const std::string& name) const { return it->second.size(); } -// Only keep the last several versoins of the Value +// Only keep the last several versions of the Value void ExecutionContext::truncHistory(const std::string& name, size_t numVersionsToKeep) { auto it = valueMap_.find(name); if (it != valueMap_.end()) { diff --git a/src/graph/context/ExecutionContext.h b/src/graph/context/ExecutionContext.h index 3cb4af51a95..ec6c917a557 100644 --- a/src/graph/context/ExecutionContext.h +++ b/src/graph/context/ExecutionContext.h @@ -61,7 +61,7 @@ class ExecutionContext { void dropResult(const std::string& name); - // Only keep the last several versoins of the Value + // Only keep the last several versions of the Value void truncHistory(const std::string& name, size_t numVersionsToKeep); bool exist(const std::string& name) const { return valueMap_.find(name) != valueMap_.end(); } diff --git a/src/graph/context/Iterator.cpp b/src/graph/context/Iterator.cpp index fad0b67d64c..e14a4e6ede4 100644 --- a/src/graph/context/Iterator.cpp +++ b/src/graph/context/Iterator.cpp @@ -324,26 +324,54 @@ const Value& GetNeighborsIter::getTagProp(const std::string& tag, const std::str return Value::kNullValue; } - auto& tagPropIndices = currentDs_->tagPropsMap; - auto index = tagPropIndices.find(tag); - if (index == tagPropIndices.end()) { - return Value::kEmpty; - } - auto propIndex = index->second.propIndices.find(prop); - if (propIndex == index->second.propIndices.end()) { - return Value::kEmpty; - } - auto colId = index->second.colIdx; + size_t colId = 0; + size_t propId = 0; auto& row = *currentRow_; - DCHECK_GT(row.size(), colId); - if (row[colId].empty()) { + if (tag == "*") { + for (auto& index : currentDs_->tagPropsMap) { + auto propIndex = index.second.propIndices.find(prop); + if (propIndex != index.second.propIndices.end()) { + colId = index.second.colIdx; + propId = propIndex->second; + DCHECK_GT(row.size(), colId); + if (row[colId].empty()) { + continue; + } + if (!row[colId].isList()) { + return Value::kNullBadType; + } + auto& list = row[colId].getList(); + auto& val = list.values[propId]; + if (val.empty()) { + continue; + } else { + return val; + } + } + } return Value::kEmpty; + } else { + auto& tagPropIndices = currentDs_->tagPropsMap; + auto index = tagPropIndices.find(tag); + if (index == tagPropIndices.end()) { + return Value::kEmpty; + } + auto propIndex = index->second.propIndices.find(prop); + if (propIndex == index->second.propIndices.end()) { + return Value::kEmpty; + } + colId = index->second.colIdx; + propId = propIndex->second; + DCHECK_GT(row.size(), colId); + if (row[colId].empty()) { + return Value::kEmpty; + } + if (!row[colId].isList()) { + return Value::kNullBadType; + } + auto& list = row[colId].getList(); + return list.values[propId]; } - if (!row[colId].isList()) { - return Value::kNullBadType; - } - auto& list = row[colId].getList(); - return list.values[propIndex->second]; } const Value& GetNeighborsIter::getEdgeProp(const std::string& edge, const std::string& prop) const { @@ -688,20 +716,37 @@ const Value& PropIter::getProp(const std::string& name, const std::string& prop) return Value::kNullValue; } auto& propsMap = dsIndex_.propsMap; - auto index = propsMap.find(name); - if (index == propsMap.end()) { - return Value::kEmpty; - } - - auto propIndex = index->second.find(prop); - if (propIndex == index->second.end()) { - VLOG(1) << "No prop found : " << prop; + size_t colId = 0; + auto& row = *iter_; + if (name == "*") { + for (auto& index : propsMap) { + auto propIndex = index.second.find(prop); + if (propIndex == index.second.end()) { + continue; + } + colId = propIndex->second; + DCHECK_GT(row.size(), colId); + auto& val = row[colId]; + if (val.empty()) { + continue; + } else { + return val; + } + } return Value::kNullValue; + } else { + auto index = propsMap.find(name); + if (index == propsMap.end()) { + return Value::kEmpty; + } + auto propIndex = index->second.find(prop); + if (propIndex == index->second.end()) { + return Value::kNullValue; + } + colId = propIndex->second; + DCHECK_GT(row.size(), colId); + return row[colId]; } - auto colId = propIndex->second; - auto& row = *iter_; - DCHECK_GT(row.size(), colId); - return row[colId]; } Value PropIter::getVertex(const std::string& name) const { diff --git a/src/graph/context/Iterator.h b/src/graph/context/Iterator.h index ff0217d8596..562117e99b6 100644 --- a/src/graph/context/Iterator.h +++ b/src/graph/context/Iterator.h @@ -436,6 +436,8 @@ class SequentialIter : public Iterator { // Notice: We only use this interface when return results to client. friend class DataCollectExecutor; + friend class AppendVerticesExecutor; + friend class TraverseExecutor; Row&& moveRow() { return std::move(*iter_); } void doReset(size_t pos) override; diff --git a/src/graph/context/ValidateContext.h b/src/graph/context/ValidateContext.h index df59eb1fc69..d3904e91792 100644 --- a/src/graph/context/ValidateContext.h +++ b/src/graph/context/ValidateContext.h @@ -68,9 +68,9 @@ class ValidateContext final { return find->second; } - void addIndex(const std::string& indexName) { indexs_.emplace(indexName); } + void addIndex(const std::string& indexName) { indexes_.emplace(indexName); } - bool hasIndex(const std::string& indexName) { return indexs_.find(indexName) != indexs_.end(); } + bool hasIndex(const std::string& indexName) { return indexes_.find(indexName) != indexes_.end(); } private: // spaces_ is the trace of space switch @@ -83,7 +83,7 @@ class ValidateContext final { std::unordered_map>; Schemas schemas_; std::unordered_set createSpaces_; - std::unordered_set indexs_; + std::unordered_set indexes_; }; } // namespace graph } // namespace nebula diff --git a/src/graph/executor/CMakeLists.txt b/src/graph/executor/CMakeLists.txt index 537156f8450..6830ad7ac5e 100644 --- a/src/graph/executor/CMakeLists.txt +++ b/src/graph/executor/CMakeLists.txt @@ -34,6 +34,8 @@ nebula_add_library( query/InnerJoinExecutor.cpp query/IndexScanExecutor.cpp query/AssignExecutor.cpp + query/TraverseExecutor.cpp + query/AppendVerticesExecutor.cpp algo/ConjunctPathExecutor.cpp algo/BFSShortestPathExecutor.cpp algo/ProduceSemiShortestPathExecutor.cpp diff --git a/src/graph/executor/Executor.cpp b/src/graph/executor/Executor.cpp index d7eb30f1759..4c8237b9e1c 100644 --- a/src/graph/executor/Executor.cpp +++ b/src/graph/executor/Executor.cpp @@ -66,6 +66,7 @@ #include "graph/executor/mutate/InsertExecutor.h" #include "graph/executor/mutate/UpdateExecutor.h" #include "graph/executor/query/AggregateExecutor.h" +#include "graph/executor/query/AppendVerticesExecutor.h" #include "graph/executor/query/AssignExecutor.h" #include "graph/executor/query/DataCollectExecutor.h" #include "graph/executor/query/DedupExecutor.h" @@ -83,6 +84,7 @@ #include "graph/executor/query/SampleExecutor.h" #include "graph/executor/query/SortExecutor.h" #include "graph/executor/query/TopNExecutor.h" +#include "graph/executor/query/TraverseExecutor.h" #include "graph/executor/query/UnionAllVersionVarExecutor.h" #include "graph/executor/query/UnionExecutor.h" #include "graph/executor/query/UnwindExecutor.h" @@ -511,6 +513,12 @@ Executor *Executor::makeExecutor(QueryContext *qctx, const PlanNode *node) { case PlanNode::Kind::kKillQuery: { return pool->add(new KillQueryExecutor(node, qctx)); } + case PlanNode::Kind::kTraverse: { + return pool->add(new TraverseExecutor(node, qctx)); + } + case PlanNode::Kind::kAppendVertices: { + return pool->add(new AppendVerticesExecutor(node, qctx)); + } case PlanNode::Kind::kUnknown: { LOG(FATAL) << "Unknown plan node kind " << static_cast(node->kind()); break; @@ -587,7 +595,7 @@ void Executor::drop() { // Make sure drop happened-after count decrement CHECK_EQ(inputVar->userCount.load(std::memory_order_acquire), 0); ectx_->dropResult(inputVar->name); - VLOG(1) << "Drop variable " << node()->outputVar(); + VLOG(1) << node()->kind() << " Drop variable " << inputVar->name; } } } diff --git a/src/graph/executor/admin/BalanceLeadersExecutor.h b/src/graph/executor/admin/BalanceLeadersExecutor.h new file mode 100644 index 00000000000..604d49bc444 --- /dev/null +++ b/src/graph/executor/admin/BalanceLeadersExecutor.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#ifndef GRAPH_EXECUTOR_ADMIN_BALANCELEADERSEXECUTOR_H_ +#define GRAPH_EXECUTOR_ADMIN_BALANCELEADERSEXECUTOR_H_ + +#include "graph/context/QueryContext.h" +#include "graph/executor/Executor.h" + +namespace nebula { +namespace graph { + +class BalanceLeadersExecutor final : public Executor { + public: + BalanceLeadersExecutor(const PlanNode *node, QueryContext *qctx) + : Executor("BalanceLeadersExecutor", node, qctx) {} + + folly::Future execute() override; + + private: + folly::Future balanceLeaders(); +}; + +} // namespace graph +} // namespace nebula + +#endif // GRAPH_EXECUTOR_ADMIN_BALANCELEADERSEXECUTOR_H_ diff --git a/src/graph/executor/admin/KillQueryExecutor.cpp b/src/graph/executor/admin/KillQueryExecutor.cpp index d3e956a95c7..e892d015788 100644 --- a/src/graph/executor/admin/KillQueryExecutor.cpp +++ b/src/graph/executor/admin/KillQueryExecutor.cpp @@ -13,7 +13,7 @@ namespace graph { folly::Future KillQueryExecutor::execute() { SCOPED_TIMER(&execTime_); - // TODO: permision check + // TODO: permission check QueriesMap toBeVerifiedQueries; QueriesMap killQueries; diff --git a/src/graph/executor/admin/ShowHostsExecutor.cpp b/src/graph/executor/admin/ShowHostsExecutor.cpp index 2ff7b5a39b0..84d4a85bb88 100644 --- a/src/graph/executor/admin/ShowHostsExecutor.cpp +++ b/src/graph/executor/admin/ShowHostsExecutor.cpp @@ -21,7 +21,7 @@ folly::Future ShowHostsExecutor::execute() { folly::Future ShowHostsExecutor::showHosts() { static constexpr char kNoPartition[] = "No valid partition"; - static constexpr char kPartitionDelimeter[] = ", "; + static constexpr char kPartitionDelimiter[] = ", "; auto *shNode = asNode(node()); auto makeTraditionalResult = [&](const std::vector &hostVec) -> DataSet { @@ -56,7 +56,7 @@ folly::Future ShowHostsExecutor::showHosts() { leaderPartsCount[l.first] += l.second.size(); leaders << l.first << ":" << l.second.size(); if (i < lPartsCount.size() - 1) { - leaders << kPartitionDelimeter; + leaders << kPartitionDelimiter; } ++i; } @@ -71,7 +71,7 @@ folly::Future ShowHostsExecutor::showHosts() { allPartsCount[p.first] += p.second.size(); parts << p.first << ":" << p.second.size(); if (i < aPartsCount.size() - 1) { - parts << kPartitionDelimeter; + parts << kPartitionDelimiter; } ++i; } @@ -95,7 +95,7 @@ folly::Future ShowHostsExecutor::showHosts() { for (const auto &spaceEntry : leaderPartsCount) { leaders << spaceEntry.first << ":" << spaceEntry.second; if (i < leaderPartsCount.size() - 1) { - leaders << kPartitionDelimeter; + leaders << kPartitionDelimiter; } ++i; } @@ -103,7 +103,7 @@ folly::Future ShowHostsExecutor::showHosts() { for (const auto &spaceEntry : allPartsCount) { parts << spaceEntry.first << ":" << spaceEntry.second; if (i < allPartsCount.size() - 1) { - parts << kPartitionDelimeter; + parts << kPartitionDelimiter; } ++i; } diff --git a/src/graph/executor/admin/ShowStatsExecutor.cpp b/src/graph/executor/admin/ShowStatsExecutor.cpp index bef1b97eece..aaaccbc2799 100644 --- a/src/graph/executor/admin/ShowStatsExecutor.cpp +++ b/src/graph/executor/admin/ShowStatsExecutor.cpp @@ -21,7 +21,7 @@ folly::Future ShowStatsExecutor::execute() { return qctx()->getMetaClient()->getStats(spaceId).via(runner()).thenValue( [this, spaceId](StatusOr resp) { if (!resp.ok()) { - LOG(ERROR) << "SpaceId: " << spaceId << ", Show staus failed: " << resp.status(); + LOG(ERROR) << "SpaceId: " << spaceId << ", Show status failed: " << resp.status(); return resp.status(); } auto statsItem = std::move(resp).value(); diff --git a/src/graph/executor/admin/SnapshotExecutor.cpp b/src/graph/executor/admin/SnapshotExecutor.cpp index 1b6375711cd..43f0d6869b3 100644 --- a/src/graph/executor/admin/SnapshotExecutor.cpp +++ b/src/graph/executor/admin/SnapshotExecutor.cpp @@ -32,7 +32,7 @@ folly::Future DropSnapshotExecutor::execute() { auto *dsNode = asNode(node()); return qctx() ->getMetaClient() - ->dropSnapshot(dsNode->getShapshotName()) + ->dropSnapshot(dsNode->getSnapshotName()) .via(runner()) .thenValue([](StatusOr resp) { if (!resp.ok()) { diff --git a/src/graph/executor/algo/ProduceAllPathsExecutor.cpp b/src/graph/executor/algo/ProduceAllPathsExecutor.cpp index 26fc027ec16..b66a4d6600f 100644 --- a/src/graph/executor/algo/ProduceAllPathsExecutor.cpp +++ b/src/graph/executor/algo/ProduceAllPathsExecutor.cpp @@ -20,7 +20,7 @@ folly::Future ProduceAllPathsExecutor::execute() { Interims interims; if (!iter->isGetNeighborsIter()) { - return Status::Error("Only accept GetNeighbotsIter."); + return Status::Error("Only accept GetNeighborsIter."); } VLOG(1) << "Edge size: " << iter->size(); for (; iter->valid(); iter->next()) { diff --git a/src/graph/executor/algo/ProduceSemiShortestPathExecutor.cpp b/src/graph/executor/algo/ProduceSemiShortestPathExecutor.cpp index 79e68ae4e97..067b5ca1935 100644 --- a/src/graph/executor/algo/ProduceSemiShortestPathExecutor.cpp +++ b/src/graph/executor/algo/ProduceSemiShortestPathExecutor.cpp @@ -214,7 +214,7 @@ folly::Future ProduceSemiShortestPathExecutor::execute() { CostPaths costPaths(weight, {std::move(path)}); currentCostPathMap[dst].emplace(src, std::move(costPaths)); } else { - // same (src, dst), diffrent edge type or rank + // same (src, dst), different edge type or rank auto currentCost = currentCostPathMap[dst][src].cost_; if (weight == currentCost) { currentCostPathMap[dst][src].paths_.emplace_back(std::move(path)); diff --git a/src/graph/executor/query/AppendVerticesExecutor.cpp b/src/graph/executor/query/AppendVerticesExecutor.cpp new file mode 100644 index 00000000000..94f67efc581 --- /dev/null +++ b/src/graph/executor/query/AppendVerticesExecutor.cpp @@ -0,0 +1,105 @@ +/* Copyright (c) 2021 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#include "graph/executor/query/AppendVerticesExecutor.h" + +using nebula::storage::GraphStorageClient; +using nebula::storage::StorageRpcResponse; +using nebula::storage::cpp2::GetPropResponse; + +namespace nebula { +namespace graph { +folly::Future AppendVerticesExecutor::execute() { return appendVertices(); } + +DataSet AppendVerticesExecutor::buildRequestDataSet(const AppendVertices *av) { + if (av == nullptr) { + return nebula::DataSet({kVid}); + } + auto valueIter = ectx_->getResult(av->inputVar()).iter(); + return buildRequestDataSetByVidType(valueIter.get(), av->src(), av->dedup()); +} + +folly::Future AppendVerticesExecutor::appendVertices() { + SCOPED_TIMER(&execTime_); + + auto *av = asNode(node()); + GraphStorageClient *storageClient = qctx()->getStorageClient(); + + DataSet vertices = buildRequestDataSet(av); + if (vertices.rows.empty()) { + return finish(ResultBuilder().value(Value(DataSet(av->colNames()))).build()); + } + + GraphStorageClient::CommonRequestParam param(av->space(), + qctx()->rctx()->session()->id(), + qctx()->plan()->id(), + qctx()->plan()->isProfileEnabled()); + time::Duration getPropsTime; + return DCHECK_NOTNULL(storageClient) + ->getProps(param, + std::move(vertices), + av->props(), + nullptr, + av->exprs(), + av->dedup(), + av->orderBy(), + av->limit(), + av->filter()) + .via(runner()) + .ensure([this, getPropsTime]() { + SCOPED_TIMER(&execTime_); + otherStats_.emplace("total_rpc", folly::sformat("{}(us)", getPropsTime.elapsedInUSec())); + }) + .thenValue([this](StorageRpcResponse &&rpcResp) { + SCOPED_TIMER(&execTime_); + addStats(rpcResp, otherStats_); + return handleResp(std::move(rpcResp)); + }); +} + +Status AppendVerticesExecutor::handleResp( + storage::StorageRpcResponse &&rpcResp) { + auto result = handleCompleteness(rpcResp, FLAGS_accept_partial_success); + NG_RETURN_IF_ERROR(result); + auto state = std::move(result).value(); + std::unordered_map map; + auto *av = asNode(node()); + auto *vFilter = av->vFilter(); + QueryExpressionContext ctx(qctx()->ectx()); + for (auto &resp : rpcResp.responses()) { + if (resp.props_ref().has_value()) { + auto iter = PropIter(std::make_shared(std::move(*resp.props_ref()))); + for (; iter.valid(); iter.next()) { + if (vFilter != nullptr) { + auto &vFilterVal = vFilter->eval(ctx(&iter)); + if (!vFilterVal.isBool() || !vFilterVal.getBool()) { + continue; + } + } + map.emplace(iter.getColumn(kVid), iter.getVertex()); + } + } + } + + auto iter = qctx()->ectx()->getResult(av->inputVar()).iter(); + auto *src = av->src(); + + DataSet ds; + ds.colNames = av->colNames(); + ds.rows.reserve(iter->size()); + for (; iter->valid(); iter->next()) { + auto dstFound = map.find(src->eval(ctx(iter.get()))); + auto row = static_cast(iter.get())->moveRow(); + if (dstFound == map.end()) { + continue; + } + row.values.emplace_back(dstFound->second); + ds.rows.emplace_back(std::move(row)); + } + return finish(ResultBuilder().value(Value(std::move(ds))).state(state).build()); +} + +} // namespace graph +} // namespace nebula diff --git a/src/graph/executor/query/AppendVerticesExecutor.h b/src/graph/executor/query/AppendVerticesExecutor.h new file mode 100644 index 00000000000..109b7a08fc2 --- /dev/null +++ b/src/graph/executor/query/AppendVerticesExecutor.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2021 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#ifndef GRAPH_EXECUTOR_QUERY_APPENDVERTICESEXECUTOR_H_ +#define GRAPH_EXECUTOR_QUERY_APPENDVERTICESEXECUTOR_H_ + +#include "graph/executor/query/GetPropExecutor.h" +#include "graph/planner/plan/Query.h" + +namespace nebula { +namespace graph { + +class AppendVerticesExecutor final : public GetPropExecutor { + public: + AppendVerticesExecutor(const PlanNode *node, QueryContext *qctx) + : GetPropExecutor("AppendVerticesExecutor", node, qctx) {} + + folly::Future execute() override; + + private: + DataSet buildRequestDataSet(const AppendVertices *gv); + + folly::Future appendVertices(); + + Status handleResp(storage::StorageRpcResponse &&rpcResp); +}; + +} // namespace graph +} // namespace nebula + +#endif // GRAPH_EXECUTOR_QUERY_GETVERTICESEXECUTOR_H_ diff --git a/src/graph/executor/query/TraverseExecutor.cpp b/src/graph/executor/query/TraverseExecutor.cpp new file mode 100644 index 00000000000..d2e23e2d458 --- /dev/null +++ b/src/graph/executor/query/TraverseExecutor.cpp @@ -0,0 +1,351 @@ +/* Copyright (c) 2021 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#include "graph/executor/query/TraverseExecutor.h" + +#include + +#include "clients/storage/GraphStorageClient.h" +#include "common/datatypes/List.h" +#include "common/datatypes/Vertex.h" +#include "common/time/ScopedTimer.h" +#include "graph/context/QueryContext.h" +#include "graph/service/GraphFlags.h" +#include "graph/util/SchemaUtil.h" + +using nebula::storage::GraphStorageClient; +using nebula::storage::StorageRpcResponse; +using nebula::storage::cpp2::GetNeighborsResponse; + +namespace nebula { +namespace graph { + +folly::Future TraverseExecutor::execute() { + range_ = traverse_->stepRange(); + auto status = buildRequestDataSet(); + if (!status.ok()) { + return error(std::move(status)); + } + return traverse(); +} + +Status TraverseExecutor::close() { + // clear the members + reqDs_.rows.clear(); + return Executor::close(); +} + +Status TraverseExecutor::buildRequestDataSet() { + SCOPED_TIMER(&execTime_); + auto inputVar = traverse_->inputVar(); + auto& inputResult = ectx_->getResult(inputVar); + auto inputIter = inputResult.iter(); + auto iter = static_cast(inputIter.get()); + + reqDs_.colNames = {kVid}; + reqDs_.rows.reserve(iter->size()); + + std::unordered_set uniqueSet; + uniqueSet.reserve(iter->size()); + std::unordered_map prev; + const auto& spaceInfo = qctx()->rctx()->session()->space(); + const auto& vidType = *(spaceInfo.spaceDesc.vid_type_ref()); + auto* src = traverse_->src(); + QueryExpressionContext ctx(ectx_); + + for (; iter->valid(); iter->next()) { + auto vid = src->eval(ctx(iter)); + if (!SchemaUtil::isValidVid(vid, vidType)) { + LOG(WARNING) << "Mismatched vid type: " << vid.type() + << ", space vid type: " << SchemaUtil::typeToString(vidType); + continue; + } + buildPath(prev, vid, iter->moveRow()); + if (!uniqueSet.emplace(vid).second) { + continue; + } + reqDs_.emplace_back(Row({std::move(vid)})); + } + paths_.emplace_back(std::move(prev)); + return Status::OK(); +} + +folly::Future TraverseExecutor::traverse() { + if (reqDs_.rows.empty()) { + VLOG(1) << "Empty input."; + DataSet emptyResult; + return finish(ResultBuilder().value(Value(std::move(emptyResult))).build()); + } + getNeighbors(); + return promise_.getFuture(); +} + +void TraverseExecutor::getNeighbors() { + currentStep_++; + time::Duration getNbrTime; + GraphStorageClient* storageClient = qctx_->getStorageClient(); + bool finalStep = isFinalStep(); + GraphStorageClient::CommonRequestParam param(traverse_->space(), + qctx()->rctx()->session()->id(), + qctx()->plan()->id(), + qctx()->plan()->isProfileEnabled()); + storageClient + ->getNeighbors(param, + reqDs_.colNames, + std::move(reqDs_.rows), + traverse_->edgeTypes(), + traverse_->edgeDirection(), + finalStep ? traverse_->statProps() : nullptr, + traverse_->vertexProps(), + traverse_->edgeProps(), + finalStep ? traverse_->exprs() : nullptr, + finalStep ? traverse_->dedup() : false, + finalStep ? traverse_->random() : false, + finalStep ? traverse_->orderBy() : std::vector(), + finalStep ? traverse_->limit() : -1, + finalStep ? traverse_->filter() : nullptr) + .via(runner()) + .thenValue([this, getNbrTime](StorageRpcResponse&& resp) mutable { + SCOPED_TIMER(&execTime_); + addStats(resp, getNbrTime.elapsedInUSec()); + handleResponse(resp); + }); +} + +void TraverseExecutor::addStats(RpcResponse& resp, int64_t getNbrTimeInUSec) { + auto& hostLatency = resp.hostLatency(); + std::stringstream ss; + ss << "{\n"; + for (size_t i = 0; i < hostLatency.size(); ++i) { + size_t size = 0u; + auto& result = resp.responses()[i]; + if (result.vertices_ref().has_value()) { + size = (*result.vertices_ref()).size(); + } + auto& info = hostLatency[i]; + ss << "{" << folly::sformat("{} exec/total/vertices: ", std::get<0>(info).toString()) + << folly::sformat("{}(us)/{}(us)/{},", std::get<1>(info), std::get<2>(info), size) << "\n" + << folly::sformat("total_rpc_time: {}(us)", getNbrTimeInUSec) << "\n"; + auto detail = getStorageDetail(result.result.latency_detail_us_ref()); + if (!detail.empty()) { + ss << folly::sformat("storage_detail: {}", detail); + } + ss << "\n}"; + } + ss << "\n}"; + otherStats_.emplace(folly::sformat("step {}", currentStep_), ss.str()); +} + +void TraverseExecutor::handleResponse(RpcResponse& resps) { + SCOPED_TIMER(&execTime_); + auto result = handleCompleteness(resps, FLAGS_accept_partial_success); + if (!result.ok()) { + promise_.setValue(std::move(result).status()); + } + + auto& responses = resps.responses(); + List list; + for (auto& resp : responses) { + auto dataset = resp.get_vertices(); + if (dataset == nullptr) { + LOG(INFO) << "Empty dataset in response"; + continue; + } + list.values.emplace_back(std::move(*dataset)); + } + auto listVal = std::make_shared(std::move(list)); + auto iter = std::make_unique(listVal); + + auto status = buildInterimPath(iter.get()); + if (!status.ok()) { + promise_.setValue(status); + return; + } + if (!isFinalStep()) { + if (reqDs_.rows.empty()) { + if (range_ != nullptr) { + promise_.setValue(buildResult()); + } else { + promise_.setValue(Status::OK()); + } + } else { + getNeighbors(); + } + } else { + promise_.setValue(buildResult()); + } +} + +Status TraverseExecutor::buildInterimPath(GetNeighborsIter* iter) { + const auto& spaceInfo = qctx()->rctx()->session()->space(); + DataSet reqDs; + reqDs.colNames = reqDs_.colNames; + size_t count = 0; + + const std::unordered_map& prev = paths_.back(); + if (currentStep_ == 1 && zeroStep()) { + paths_.emplace_back(); + NG_RETURN_IF_ERROR(handleZeroStep(prev, iter->getVertices(), paths_.back(), count)); + // If 0..0 case, release memory and return immediately. + if (range_ != nullptr && range_->max() == 0) { + releasePrevPaths(count); + return Status::OK(); + } + } + paths_.emplace_back(); + std::unordered_map& current = paths_.back(); + + auto* vFilter = traverse_->vFilter(); + auto* eFilter = traverse_->eFilter(); + QueryExpressionContext ctx(ectx_); + std::unordered_set uniqueDst; + + for (; iter->valid(); iter->next()) { + auto& dst = iter->getEdgeProp("*", kDst); + if (!SchemaUtil::isValidVid(dst, *(spaceInfo.spaceDesc.vid_type_ref()))) { + continue; + } + if (vFilter != nullptr && currentStep_ == 1) { + auto& vFilterVal = vFilter->eval(ctx(iter)); + if (!vFilterVal.isBool() || !vFilterVal.getBool()) { + continue; + } + } + if (eFilter != nullptr) { + auto& eFilterVal = eFilter->eval(ctx(iter)); + if (!eFilterVal.isBool() || !eFilterVal.getBool()) { + continue; + } + } + auto srcV = iter->getVertex(); + auto e = iter->getEdge(); + // Join on dst = src + auto pathToSrcFound = prev.find(srcV.getVertex().vid); + if (pathToSrcFound == prev.end()) { + return Status::Error("Can't find prev paths."); + } + const auto& paths = pathToSrcFound->second; + for (auto& prevPath : paths) { + if (hasSameEdge(prevPath, e.getEdge())) { + continue; + } + if (uniqueDst.emplace(dst).second) { + reqDs.rows.emplace_back(Row({std::move(dst)})); + } + auto path = prevPath; + if (currentStep_ == 1) { + path.values.emplace_back(srcV); + List neighbors; + neighbors.values.emplace_back(e); + path.values.emplace_back(std::move(neighbors)); + buildPath(current, dst, std::move(path)); + ++count; + } else { + auto& eList = path.values.back().mutableList().values; + eList.emplace_back(srcV); + eList.emplace_back(e); + buildPath(current, dst, std::move(path)); + ++count; + } + } // `prevPath' + } // `iter' + + releasePrevPaths(count); + reqDs_ = std::move(reqDs); + return Status::OK(); +} + +void TraverseExecutor::buildPath(std::unordered_map>& currentPaths, + const Value& dst, + Row&& path) { + auto pathToDstFound = currentPaths.find(dst); + if (pathToDstFound == currentPaths.end()) { + Paths interimPaths; + interimPaths.emplace_back(std::move(path)); + currentPaths.emplace(dst, std::move(interimPaths)); + } else { + auto& interimPaths = pathToDstFound->second; + interimPaths.emplace_back(std::move(path)); + } +} + +Status TraverseExecutor::buildResult() { + // This means we are reaching a dead end, return empty. + if (range_ != nullptr && currentStep_ < range_->min()) { + return finish(ResultBuilder().value(Value(DataSet())).build()); + } + + DataSet result; + result.colNames = traverse_->colNames(); + result.rows.reserve(cnt_); + for (auto& currentStepPaths : paths_) { + for (auto& paths : currentStepPaths) { + std::move(paths.second.begin(), paths.second.end(), std::back_inserter(result.rows)); + } + } + + return finish(ResultBuilder().value(Value(std::move(result))).build()); +} + +bool TraverseExecutor::hasSameEdge(const Row& prevPath, const Edge& currentEdge) { + for (const auto& v : prevPath.values) { + if (v.isList()) { + for (const auto& e : v.getList().values) { + if (e.isEdge() && e.getEdge().keyEqual(currentEdge)) { + return true; + } + } + } + } + return false; +} + +void TraverseExecutor::releasePrevPaths(size_t cnt) { + if (range_ != nullptr) { + if (currentStep_ == range_->min() && paths_.size() > 1) { + auto rangeEnd = paths_.begin(); + std::advance(rangeEnd, paths_.size() - 1); + paths_.erase(paths_.begin(), rangeEnd); + } else if (range_->min() == 0 && currentStep_ == 1 && paths_.size() > 1) { + paths_.pop_front(); + } + + if (currentStep_ >= range_->min()) { + cnt_ += cnt; + } + } else { + paths_.pop_front(); + cnt_ = cnt; + } +} + +Status TraverseExecutor::handleZeroStep(const std::unordered_map& prev, + List&& vertices, + std::unordered_map& zeroSteps, + size_t& count) { + std::unordered_set uniqueSrc; + for (auto& srcV : vertices.values) { + auto src = srcV.getVertex().vid; + if (!uniqueSrc.emplace(src).second) { + continue; + } + auto pathToSrcFound = prev.find(src); + if (pathToSrcFound == prev.end()) { + return Status::Error("Can't find prev paths."); + } + const auto& paths = pathToSrcFound->second; + for (auto path : paths) { + path.values.emplace_back(srcV); + List neighbors; + neighbors.values.emplace_back(srcV); + path.values.emplace_back(std::move(neighbors)); + buildPath(zeroSteps, src, std::move(path)); + ++count; + } + } + return Status::OK(); +} +} // namespace graph +} // namespace nebula diff --git a/src/graph/executor/query/TraverseExecutor.h b/src/graph/executor/query/TraverseExecutor.h new file mode 100644 index 00000000000..4f2802cb68d --- /dev/null +++ b/src/graph/executor/query/TraverseExecutor.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2021 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#ifndef EXECUTOR_QUERY_TRAVERSEEXECUTOR_H_ +#define EXECUTOR_QUERY_TRAVERSEEXECUTOR_H_ + +#include + +#include "clients/storage/GraphStorageClient.h" +#include "common/base/StatusOr.h" +#include "common/datatypes/Value.h" +#include "common/datatypes/Vertex.h" +#include "graph/executor/StorageAccessExecutor.h" +#include "graph/planner/plan/Query.h" +#include "interface/gen-cpp2/storage_types.h" + +namespace nebula { +namespace graph { + +using RpcResponse = storage::StorageRpcResponse; + +class TraverseExecutor final : public StorageAccessExecutor { + public: + TraverseExecutor(const PlanNode* node, QueryContext* qctx) + : StorageAccessExecutor("Traverse", node, qctx) { + traverse_ = asNode(node); + } + + folly::Future execute() override; + + Status close() override; + + private: + using Dst = Value; + using Paths = std::vector; + Status buildRequestDataSet(); + + folly::Future traverse(); + + void addStats(RpcResponse& resps, int64_t getNbrTimeInUSec); + + void getNeighbors(); + + void handleResponse(RpcResponse& resps); + + Status buildInterimPath(GetNeighborsIter* iter); + + Status buildResult(); + + bool isFinalStep() const { + return (range_ == nullptr && currentStep_ == 1) || + (range_ != nullptr && (currentStep_ == range_->max() || range_->max() == 0)); + } + + bool zeroStep() const { return range_ != nullptr && range_->min() == 0; } + + bool hasSameEdge(const Row& prevPath, const Edge& currentEdge); + + void releasePrevPaths(size_t cnt); + + void buildPath(std::unordered_map>& currentPaths, + const Value& dst, + Row&& path); + + Status handleZeroStep(const std::unordered_map& prev, + List&& vertices, + std::unordered_map& zeroSteps, + size_t& count); + + private: + DataSet reqDs_; + const Traverse* traverse_{nullptr}; + folly::Promise promise_; + MatchStepRange* range_{nullptr}; + size_t currentStep_{0}; + std::list> paths_; + size_t cnt_{0}; +}; + +} // namespace graph +} // namespace nebula + +#endif // EXECUTOR_QUERY_TRAVERSEEXECUTOR_H_ diff --git a/src/graph/executor/query/UnionAllVersionVarExecutor.cpp b/src/graph/executor/query/UnionAllVersionVarExecutor.cpp index 59cda3eb2aa..856ba363bd0 100644 --- a/src/graph/executor/query/UnionAllVersionVarExecutor.cpp +++ b/src/graph/executor/query/UnionAllVersionVarExecutor.cpp @@ -14,7 +14,7 @@ namespace graph { folly::Future UnionAllVersionVarExecutor::execute() { SCOPED_TIMER(&execTime_); auto* UnionAllVersionVarNode = asNode(node()); - // Retrive all versions of inputVar + // Retrieve all versions of inputVar auto& results = ectx_->getHistory(UnionAllVersionVarNode->inputVar()); DCHECK_GT(results.size(), 0); // List of iterators to be unioned diff --git a/src/graph/executor/test/CartesianProductTest.cpp b/src/graph/executor/test/CartesianProductTest.cpp index c09b239e8f3..1e73d47ef95 100644 --- a/src/graph/executor/test/CartesianProductTest.cpp +++ b/src/graph/executor/test/CartesianProductTest.cpp @@ -106,7 +106,7 @@ TEST_F(CartesianProductTest, twoVars) { checkResult(expected, cp->outputVar()); } -TEST_F(CartesianProductTest, thressVars) { +TEST_F(CartesianProductTest, threeVars) { auto* cp = CartesianProduct::make(qctx_.get(), nullptr); cp->addVar("ds1"); cp->addVar("ds2"); diff --git a/src/graph/executor/test/DedupTest.cpp b/src/graph/executor/test/DedupTest.cpp index 0b75ddd82f4..3692c49933a 100644 --- a/src/graph/executor/test/DedupTest.cpp +++ b/src/graph/executor/test/DedupTest.cpp @@ -18,7 +18,7 @@ class DedupTest : public QueryTestBase { void SetUp() override { QueryTestBase::SetUp(); } }; -#define DEDUP_RESUTL_CHECK(inputName, outputName, sentence, expected) \ +#define DEDUP_RESULT_CHECK(inputName, outputName, sentence, expected) \ do { \ qctx_->symTable()->newVariable(outputName); \ auto yieldSentence = getYieldSentence(sentence, qctx_.get()); \ @@ -43,10 +43,10 @@ class DedupTest : public QueryTestBase { \ auto proExe = std::make_unique(project, qctx_.get()); \ EXPECT_TRUE(proExe->execute().get().ok()); \ - auto& proSesult = qctx_->ectx()->getResult(project->outputVar()); \ + auto& proResult = qctx_->ectx()->getResult(project->outputVar()); \ \ - EXPECT_EQ(proSesult.value().getDataSet(), expected); \ - EXPECT_EQ(proSesult.state(), Result::State::kSuccess); \ + EXPECT_EQ(proResult.value().getDataSet(), expected); \ + EXPECT_EQ(proResult.state(), Result::State::kSuccess); \ } while (false) TEST_F(DedupTest, TestSequential) { @@ -60,17 +60,17 @@ TEST_F(DedupTest, TestSequential) { auto sentence = "YIELD DISTINCT $-.vid as vid, $-.v_name as name, $-.v_age as age, " "$-.v_dst as dst, $-.e_start_year as start, $-.e_end_year as end"; - DEDUP_RESUTL_CHECK("input_sequential", "dedup_sequential", sentence, expected); + DEDUP_RESULT_CHECK("input_sequential", "dedup_sequential", sentence, expected); } TEST_F(DedupTest, TestEmpty) { DataSet expected({"name"}); - DEDUP_RESUTL_CHECK("empty", "dedup_sequential", "YIELD DISTINCT $-.v_dst as name", expected); + DEDUP_RESULT_CHECK("empty", "dedup_sequential", "YIELD DISTINCT $-.v_dst as name", expected); } TEST_F(DedupTest, WrongTypeIterator) { DataSet expected; - DEDUP_RESUTL_CHECK( + DEDUP_RESULT_CHECK( "input_neighbor", "dedup_sequential", "YIELD DISTINCT $-.v_dst as name", expected); } } // namespace graph diff --git a/src/graph/executor/test/FilterTest.cpp b/src/graph/executor/test/FilterTest.cpp index dcbb5fec98a..883e331ef0c 100644 --- a/src/graph/executor/test/FilterTest.cpp +++ b/src/graph/executor/test/FilterTest.cpp @@ -19,7 +19,7 @@ class FilterTest : public QueryTestBase { void SetUp() override { QueryTestBase::SetUp(); } }; -#define FILTER_RESUTL_CHECK(inputName, outputName, sentence, expected) \ +#define FILTER_RESULT_CHECK(inputName, outputName, sentence, expected) \ do { \ qctx_->symTable()->newVariable(outputName); \ auto yieldSentence = getYieldSentence(sentence, qctx_.get()); \ @@ -44,10 +44,10 @@ class FilterTest : public QueryTestBase { \ auto proExe = std::make_unique(project, qctx_.get()); \ EXPECT_TRUE(proExe->execute().get().ok()); \ - auto& proSesult = qctx_->ectx()->getResult(project->outputVar()); \ + auto& proResult = qctx_->ectx()->getResult(project->outputVar()); \ \ - EXPECT_EQ(proSesult.value().getDataSet(), expected); \ - EXPECT_EQ(proSesult.state(), Result::State::kSuccess); \ + EXPECT_EQ(proResult.value().getDataSet(), expected); \ + EXPECT_EQ(proResult.state(), Result::State::kSuccess); \ } while (false) TEST_F(FilterTest, TestGetNeighbors_src_dst) { @@ -55,7 +55,7 @@ TEST_F(FilterTest, TestGetNeighbors_src_dst) { expected.emplace_back(Row({Value("Ann")})); expected.emplace_back(Row({Value("Ann")})); expected.emplace_back(Row({Value("Tom")})); - FILTER_RESUTL_CHECK("input_neighbor", + FILTER_RESULT_CHECK("input_neighbor", "filter_getNeighbor", "YIELD $^.person.name AS name WHERE study.start_year >= 2010", expected); @@ -65,7 +65,7 @@ TEST_F(FilterTest, TestSequential) { DataSet expected({"name"}); expected.emplace_back(Row({Value("Ann")})); expected.emplace_back(Row({Value("Ann")})); - FILTER_RESUTL_CHECK("input_sequential", + FILTER_RESULT_CHECK("input_sequential", "filter_sequential", "YIELD $-.v_name AS name WHERE $-.e_start_year >= 2010", expected); @@ -73,13 +73,13 @@ TEST_F(FilterTest, TestSequential) { TEST_F(FilterTest, TestNullValue) { DataSet expected({"name"}); - FILTER_RESUTL_CHECK( + FILTER_RESULT_CHECK( "input_sequential", "filter_sequential", "YIELD $-.v_name AS name WHERE NULL", expected); } TEST_F(FilterTest, TestEmpty) { DataSet expected({"name"}); - FILTER_RESUTL_CHECK("empty", + FILTER_RESULT_CHECK("empty", "filter_empty", "YIELD $^.person.name AS name WHERE study.start_year >= 2010", expected); diff --git a/src/graph/executor/test/LimitTest.cpp b/src/graph/executor/test/LimitTest.cpp index 06305fa7ec8..3117d0fa826 100644 --- a/src/graph/executor/test/LimitTest.cpp +++ b/src/graph/executor/test/LimitTest.cpp @@ -17,7 +17,7 @@ namespace nebula { namespace graph { class LimitTest : public QueryTestBase {}; -#define LIMIT_RESUTL_CHECK(outputName, offset, count, expected) \ +#define LIMIT_RESULT_CHECK(outputName, offset, count, expected) \ do { \ qctx_->symTable()->newVariable(outputName); \ auto start = StartNode::make(qctx_.get()); \ @@ -45,7 +45,7 @@ TEST_F(LimitTest, SequentialInRange1) { DataSet expected({"name", "start"}); expected.emplace_back(Row({Value("Joy"), Value(2009)})); expected.emplace_back(Row({Value("Tom"), Value(2008)})); - LIMIT_RESUTL_CHECK("limit_in_sequential1", 1, 2, expected); + LIMIT_RESULT_CHECK("limit_in_sequential1", 1, 2, expected); } TEST_F(LimitTest, SequentialInRange2) { @@ -54,7 +54,7 @@ TEST_F(LimitTest, SequentialInRange2) { expected.emplace_back(Row({Value("Joy"), Value(2009)})); expected.emplace_back(Row({Value("Tom"), Value(2008)})); expected.emplace_back(Row({Value("Kate"), Value(2009)})); - LIMIT_RESUTL_CHECK("limit_in_sequential2", 0, 4, expected); + LIMIT_RESULT_CHECK("limit_in_sequential2", 0, 4, expected); } TEST_F(LimitTest, SequentialOutRange1) { @@ -65,12 +65,12 @@ TEST_F(LimitTest, SequentialOutRange1) { expected.emplace_back(Row({Value("Kate"), Value(2009)})); expected.emplace_back(Row({Value("Ann"), Value(2010)})); expected.emplace_back(Row({Value("Lily"), Value(2009)})); - LIMIT_RESUTL_CHECK("limit_out_sequential1", 0, 7, expected); + LIMIT_RESULT_CHECK("limit_out_sequential1", 0, 7, expected); } TEST_F(LimitTest, getNeighborOutRange2) { DataSet expected({"name", "start"}); - LIMIT_RESUTL_CHECK("limit_out_sequential2", 6, 2, expected); + LIMIT_RESULT_CHECK("limit_out_sequential2", 6, 2, expected); } } // namespace graph } // namespace nebula diff --git a/src/graph/executor/test/ProduceAllPathsTest.cpp b/src/graph/executor/test/ProduceAllPathsTest.cpp index 06c9dfe6fd4..ebce7928286 100644 --- a/src/graph/executor/test/ProduceAllPathsTest.cpp +++ b/src/graph/executor/test/ProduceAllPathsTest.cpp @@ -198,7 +198,7 @@ class ProduceAllPathsTest : public testing::Test { ds3.rows.emplace_back(std::move(row)); } } - thridStepResult_ = std::move(ds3); + thirdStepResult_ = std::move(ds3); { DataSet ds; @@ -221,7 +221,7 @@ class ProduceAllPathsTest : public testing::Test { std::unique_ptr qctx_; DataSet firstStepResult_; DataSet secondStepResult_; - DataSet thridStepResult_; + DataSet thirdStepResult_; }; TEST_F(ProduceAllPathsTest, AllPath) { @@ -408,7 +408,7 @@ TEST_F(ProduceAllPathsTest, AllPath) { { ResultBuilder builder; List datasets; - datasets.values.emplace_back(std::move(thridStepResult_)); + datasets.values.emplace_back(std::move(thirdStepResult_)); builder.value(std::move(datasets)).iter(Iterator::Kind::kGetNeighbors); qctx_->ectx()->setResult("input", builder.build()); diff --git a/src/graph/executor/test/ProduceSemiShortestPathTest.cpp b/src/graph/executor/test/ProduceSemiShortestPathTest.cpp index 92f49b08d0b..963d7d2f453 100644 --- a/src/graph/executor/test/ProduceSemiShortestPathTest.cpp +++ b/src/graph/executor/test/ProduceSemiShortestPathTest.cpp @@ -192,7 +192,7 @@ class ProduceSemiShortestPathTest : public testing::Test { ds3.rows.emplace_back(std::move(row)); } } - thridStepResult_ = std::move(ds3); + thirdStepResult_ = std::move(ds3); { DataSet ds; @@ -215,7 +215,7 @@ class ProduceSemiShortestPathTest : public testing::Test { std::unique_ptr qctx_; DataSet firstStepResult_; DataSet secondStepResult_; - DataSet thridStepResult_; + DataSet thirdStepResult_; }; TEST_F(ProduceSemiShortestPathTest, ShortestPath) { @@ -441,7 +441,7 @@ TEST_F(ProduceSemiShortestPathTest, ShortestPath) { { ResultBuilder builder; List datasets; - datasets.values.emplace_back(std::move(thridStepResult_)); + datasets.values.emplace_back(std::move(thirdStepResult_)); builder.value(std::move(datasets)).iter(Iterator::Kind::kGetNeighbors); qctx_->ectx()->setResult("input", builder.build()); diff --git a/src/graph/executor/test/SampleTest.cpp b/src/graph/executor/test/SampleTest.cpp index e52f5ca9dca..d786b0f802f 100644 --- a/src/graph/executor/test/SampleTest.cpp +++ b/src/graph/executor/test/SampleTest.cpp @@ -17,7 +17,7 @@ namespace nebula { namespace graph { class SampleTest : public QueryTestBase {}; -#define SAMPLE_RESUTL_CHECK(outputName, count, expect) \ +#define SAMPLE_RESULT_CHECK(outputName, count, expect) \ do { \ qctx_->symTable()->newVariable(outputName); \ auto start = StartNode::make(qctx_.get()); \ @@ -41,13 +41,13 @@ class SampleTest : public QueryTestBase {}; EXPECT_EQ(proResult.state(), Result::State::kSuccess); \ } while (false) -TEST_F(SampleTest, SequentialInRange2) { SAMPLE_RESUTL_CHECK("sample_in_sequential2", 4, 4); } +TEST_F(SampleTest, SequentialInRange2) { SAMPLE_RESULT_CHECK("sample_in_sequential2", 4, 4); } -TEST_F(SampleTest, SequentialOutRange1) { SAMPLE_RESUTL_CHECK("sample_out_sequential3", 7, 6); } +TEST_F(SampleTest, SequentialOutRange1) { SAMPLE_RESULT_CHECK("sample_out_sequential3", 7, 6); } -TEST_F(SampleTest, SequentialOutRange2) { SAMPLE_RESUTL_CHECK("sample_out_sequential4", 8, 6); } +TEST_F(SampleTest, SequentialOutRange2) { SAMPLE_RESULT_CHECK("sample_out_sequential4", 8, 6); } -#define SAMPLE_GN_RESUTL_CHECK(outputName, count, expect) \ +#define SAMPLE_GN_RESULT_CHECK(outputName, count, expect) \ do { \ qctx_->symTable()->newVariable(outputName); \ auto start = StartNode::make(qctx_.get()); \ @@ -70,11 +70,11 @@ TEST_F(SampleTest, SequentialOutRange2) { SAMPLE_RESUTL_CHECK("sample_out_sequen EXPECT_EQ(proResult.state(), Result::State::kSuccess); \ } while (false) -TEST_F(SampleTest, GN2) { SAMPLE_GN_RESUTL_CHECK("sample_in_gn2", 4, 4); } +TEST_F(SampleTest, GN2) { SAMPLE_GN_RESULT_CHECK("sample_in_gn2", 4, 4); } -TEST_F(SampleTest, GNOutOfRange1) { SAMPLE_GN_RESUTL_CHECK("sample_out_gn1", 6, 4); } +TEST_F(SampleTest, GNOutOfRange1) { SAMPLE_GN_RESULT_CHECK("sample_out_gn1", 6, 4); } -TEST_F(SampleTest, GNOutOfRange2) { SAMPLE_GN_RESUTL_CHECK("sample_out_gn2", 7, 4); } +TEST_F(SampleTest, GNOutOfRange2) { SAMPLE_GN_RESULT_CHECK("sample_out_gn2", 7, 4); } } // namespace graph } // namespace nebula diff --git a/src/graph/executor/test/SetExecutorTest.cpp b/src/graph/executor/test/SetExecutorTest.cpp index aee6e891a24..9bac46afe25 100644 --- a/src/graph/executor/test/SetExecutorTest.cpp +++ b/src/graph/executor/test/SetExecutorTest.cpp @@ -157,7 +157,7 @@ TEST_F(SetExecutorTest, TestUnionAll) { } } -TEST_F(SetExecutorTest, TestGetNeighobrsIterator) { +TEST_F(SetExecutorTest, TestGetNeighborsIterator) { auto left = StartNode::make(qctx_.get()); auto right = StartNode::make(qctx_.get()); auto unionNode = Union::make(qctx_.get(), left, right); diff --git a/src/graph/executor/test/SortTest.cpp b/src/graph/executor/test/SortTest.cpp index ac2774d4470..f7223c158a7 100644 --- a/src/graph/executor/test/SortTest.cpp +++ b/src/graph/executor/test/SortTest.cpp @@ -17,7 +17,7 @@ namespace graph { class SortTest : public QueryTestBase {}; -#define SORT_RESUTL_CHECK(input_name, outputName, multi, factors, expected) \ +#define SORT_RESULT_CHECK(input_name, outputName, multi, factors, expected) \ do { \ qctx_->symTable()->newVariable(outputName); \ auto start = StartNode::make(qctx_.get()); \ @@ -59,7 +59,7 @@ TEST_F(SortTest, sortOneColAsc) { expected.emplace_back(Row({Value::kNullValue})); std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::ASCEND)); - SORT_RESUTL_CHECK("input_sequential", "sort_one_col_asc", false, factors, expected); + SORT_RESULT_CHECK("input_sequential", "sort_one_col_asc", false, factors, expected); } TEST_F(SortTest, sortOneColDes) { @@ -72,7 +72,7 @@ TEST_F(SortTest, sortOneColDes) { expected.emplace_back(Row({18})); std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::DESCEND)); - SORT_RESUTL_CHECK("input_sequential", "sort_one_col_des", false, factors, expected); + SORT_RESULT_CHECK("input_sequential", "sort_one_col_des", false, factors, expected); } TEST_F(SortTest, sortTwoColsAscAsc) { @@ -86,7 +86,7 @@ TEST_F(SortTest, sortTwoColsAscAsc) { std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::ASCEND)); factors.emplace_back(std::make_pair(4, OrderFactor::OrderType::ASCEND)); - SORT_RESUTL_CHECK("input_sequential", "sort_two_cols_asc_asc", true, factors, expected); + SORT_RESULT_CHECK("input_sequential", "sort_two_cols_asc_asc", true, factors, expected); } TEST_F(SortTest, sortTwoColsAscDes) { @@ -100,7 +100,7 @@ TEST_F(SortTest, sortTwoColsAscDes) { std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::ASCEND)); factors.emplace_back(std::make_pair(4, OrderFactor::OrderType::DESCEND)); - SORT_RESUTL_CHECK("input_sequential", "sort_two_cols_asc_des", true, factors, expected); + SORT_RESULT_CHECK("input_sequential", "sort_two_cols_asc_des", true, factors, expected); } TEST_F(SortTest, sortTwoColDesDes) { @@ -114,7 +114,7 @@ TEST_F(SortTest, sortTwoColDesDes) { std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::DESCEND)); factors.emplace_back(std::make_pair(4, OrderFactor::OrderType::DESCEND)); - SORT_RESUTL_CHECK("input_sequential", "sort_two_cols_des_des", true, factors, expected); + SORT_RESULT_CHECK("input_sequential", "sort_two_cols_des_des", true, factors, expected); } TEST_F(SortTest, sortTwoColDesDes_union) { @@ -128,7 +128,7 @@ TEST_F(SortTest, sortTwoColDesDes_union) { std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::DESCEND)); factors.emplace_back(std::make_pair(4, OrderFactor::OrderType::DESCEND)); - SORT_RESUTL_CHECK("union_sequential", "union_sort_two_cols_des_des", true, factors, expected); + SORT_RESULT_CHECK("union_sequential", "union_sort_two_cols_des_des", true, factors, expected); } } // namespace graph } // namespace nebula diff --git a/src/graph/executor/test/TopNTest.cpp b/src/graph/executor/test/TopNTest.cpp index 24170b8c0d6..d5778a11132 100644 --- a/src/graph/executor/test/TopNTest.cpp +++ b/src/graph/executor/test/TopNTest.cpp @@ -17,7 +17,7 @@ namespace graph { class TopNTest : public QueryTestBase {}; -#define TOPN_RESUTL_CHECK(input_name, outputName, multi, factors, offset, count, expected) \ +#define TOPN_RESULT_CHECK(input_name, outputName, multi, factors, offset, count, expected) \ do { \ qctx_->symTable()->newVariable(outputName); \ auto start = StartNode::make(qctx_.get()); \ @@ -57,7 +57,7 @@ TEST_F(TopNTest, topnOneColAsc) { expected.emplace_back(Row({20})); std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::ASCEND)); - TOPN_RESUTL_CHECK("input_sequential", "topn_one_col_asc", false, factors, 0, 4, expected); + TOPN_RESULT_CHECK("input_sequential", "topn_one_col_asc", false, factors, 0, 4, expected); } TEST_F(TopNTest, topnOneColDes) { @@ -68,7 +68,7 @@ TEST_F(TopNTest, topnOneColDes) { expected.emplace_back(Row({18})); std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::DESCEND)); - TOPN_RESUTL_CHECK("input_sequential", "topn_one_col_des", false, factors, 2, 9, expected); + TOPN_RESULT_CHECK("input_sequential", "topn_one_col_des", false, factors, 2, 9, expected); } TEST_F(TopNTest, topnTwoColsAscAsc) { @@ -79,7 +79,7 @@ TEST_F(TopNTest, topnTwoColsAscAsc) { std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::ASCEND)); factors.emplace_back(std::make_pair(4, OrderFactor::OrderType::ASCEND)); - TOPN_RESUTL_CHECK("input_sequential", "topn_two_cols_asc_asc", true, factors, 2, 3, expected); + TOPN_RESULT_CHECK("input_sequential", "topn_two_cols_asc_asc", true, factors, 2, 3, expected); } TEST_F(TopNTest, topnTwoColsAscDes) { @@ -89,7 +89,7 @@ TEST_F(TopNTest, topnTwoColsAscDes) { std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::ASCEND)); factors.emplace_back(std::make_pair(4, OrderFactor::OrderType::DESCEND)); - TOPN_RESUTL_CHECK("input_sequential", "topn_two_cols_asc_des", true, factors, 0, 2, expected); + TOPN_RESULT_CHECK("input_sequential", "topn_two_cols_asc_des", true, factors, 0, 2, expected); } TEST_F(TopNTest, topnTwoColDesDes) { @@ -97,7 +97,7 @@ TEST_F(TopNTest, topnTwoColDesDes) { std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::DESCEND)); factors.emplace_back(std::make_pair(4, OrderFactor::OrderType::DESCEND)); - TOPN_RESUTL_CHECK("input_sequential", "topn_two_cols_des_des", true, factors, 10, 5, expected); + TOPN_RESULT_CHECK("input_sequential", "topn_two_cols_des_des", true, factors, 10, 5, expected); } TEST_F(TopNTest, topnTwoColDesAsc) { @@ -110,7 +110,7 @@ TEST_F(TopNTest, topnTwoColDesAsc) { std::vector> factors; factors.emplace_back(std::make_pair(2, OrderFactor::OrderType::DESCEND)); factors.emplace_back(std::make_pair(4, OrderFactor::OrderType::ASCEND)); - TOPN_RESUTL_CHECK("input_sequential", "topn_two_cols_des_asc", true, factors, 1, 9, expected); + TOPN_RESULT_CHECK("input_sequential", "topn_two_cols_des_asc", true, factors, 1, 9, expected); } } // namespace graph } // namespace nebula diff --git a/src/graph/optimizer/rule/GeoPredicateIndexScanBaseRule.cpp b/src/graph/optimizer/rule/GeoPredicateIndexScanBaseRule.cpp index 13a01c52db2..3acad7ba487 100644 --- a/src/graph/optimizer/rule/GeoPredicateIndexScanBaseRule.cpp +++ b/src/graph/optimizer/rule/GeoPredicateIndexScanBaseRule.cpp @@ -122,7 +122,7 @@ StatusOr GeoPredicateIndexScanBaseRule::transform( auto scanNode = IndexScan::make(ctx->qctx(), nullptr); OptimizerUtils::copyIndexScanData(scan, scanNode); scanNode->setIndexQueryContext(std::move(idxCtxs)); - // TODO(jie): geo predicate's caculation is a little heavy, + // TODO(jie): geo predicate's calculation is a little heavy, // which is not suitable to push down to the storage scanNode->setOutputVar(filter->outputVar()); scanNode->setColNames(filter->colNames()); diff --git a/src/graph/optimizer/rule/IndexScanRule.cpp b/src/graph/optimizer/rule/IndexScanRule.cpp index 399a4987ee1..454e08e2d5a 100644 --- a/src/graph/optimizer/rule/IndexScanRule.cpp +++ b/src/graph/optimizer/rule/IndexScanRule.cpp @@ -241,7 +241,7 @@ Status IndexScanRule::appendColHint(std::vector& hints, begin = {item.value_, true}; break; } - // because only type for bool is true/false, which can not satisify [start, + // because only type for bool is true/false, which can not satisfy [start, // end) if (col.get_type().get_type() == nebula::cpp2::PropertyType::BOOL) { return Status::SemanticError("Range scan for bool type is illegal"); diff --git a/src/graph/planner/CMakeLists.txt b/src/graph/planner/CMakeLists.txt index b79f97edefd..f5e0eab5d70 100644 --- a/src/graph/planner/CMakeLists.txt +++ b/src/graph/planner/CMakeLists.txt @@ -25,7 +25,6 @@ nebula_add_library( match/StartVidFinder.cpp match/PropIndexSeek.cpp match/VertexIdSeek.cpp - match/Expand.cpp match/LabelIndexSeek.cpp plan/PlanNode.cpp plan/ExecutionPlan.cpp diff --git a/src/graph/planner/PlannersRegister.cpp b/src/graph/planner/PlannersRegister.cpp index 04bab266396..e682ad243b8 100644 --- a/src/graph/planner/PlannersRegister.cpp +++ b/src/graph/planner/PlannersRegister.cpp @@ -23,13 +23,13 @@ namespace nebula { namespace graph { -void PlannersRegister::registPlanners() { - registDDL(); - registSequential(); - registMatch(); +void PlannersRegister::registerPlanners() { + registerDDL(); + registerSequential(); + registerMatch(); } -void PlannersRegister::registDDL() { +void PlannersRegister::registerDDL() { { auto& planners = Planner::plannersMap()[Sentence::Kind::kAlterTag]; planners.emplace_back(&AlterTagPlanner::match, &AlterTagPlanner::make); @@ -48,7 +48,7 @@ void PlannersRegister::registDDL() { } } -void PlannersRegister::registSequential() { +void PlannersRegister::registerSequential() { { auto& planners = Planner::plannersMap()[Sentence::Kind::kSequential]; planners.emplace_back(&SequentialPlanner::match, &SequentialPlanner::make); @@ -79,7 +79,7 @@ void PlannersRegister::registSequential() { } } -void PlannersRegister::registMatch() { +void PlannersRegister::registerMatch() { auto& planners = Planner::plannersMap()[Sentence::Kind::kMatch]; planners.emplace_back(&MatchPlanner::match, &MatchPlanner::make); diff --git a/src/graph/planner/PlannersRegister.h b/src/graph/planner/PlannersRegister.h index 5577e6e1588..bdadb940756 100644 --- a/src/graph/planner/PlannersRegister.h +++ b/src/graph/planner/PlannersRegister.h @@ -14,12 +14,12 @@ class PlannersRegister final { PlannersRegister() = delete; ~PlannersRegister() = delete; - static void registPlanners(); + static void registerPlanners(); private: - static void registDDL(); - static void registSequential(); - static void registMatch(); + static void registerDDL(); + static void registerSequential(); + static void registerMatch(); }; } // namespace graph diff --git a/src/graph/planner/match/Expand.cpp b/src/graph/planner/match/Expand.cpp deleted file mode 100644 index 6a546c8f145..00000000000 --- a/src/graph/planner/match/Expand.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/* Copyright (c) 2020 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "graph/planner/match/Expand.h" - -#include "graph/planner/match/MatchSolver.h" -#include "graph/planner/match/SegmentsConnector.h" -#include "graph/planner/plan/Logic.h" -#include "graph/planner/plan/Query.h" -#include "graph/util/AnonColGenerator.h" -#include "graph/util/ExpressionUtils.h" -#include "graph/visitor/RewriteVisitor.h" - -using nebula::storage::cpp2::EdgeProp; -using nebula::storage::cpp2::VertexProp; -using PNKind = nebula::graph::PlanNode::Kind; - -namespace nebula { -namespace graph { - -static std::unique_ptr> genVertexProps() { - return std::make_unique>(); -} - -std::unique_ptr> Expand::genEdgeProps(const EdgeInfo& edge) { - auto edgeProps = std::make_unique>(); - for (auto edgeType : edge.edgeTypes) { - auto edgeSchema = matchCtx_->qctx->schemaMng()->getEdgeSchema(matchCtx_->space.id, edgeType); - - switch (edge.direction) { - case Direction::OUT_EDGE: { - if (reversely_) { - edgeType = -edgeType; - } - break; - } - case Direction::IN_EDGE: { - if (!reversely_) { - edgeType = -edgeType; - } - break; - } - case Direction::BOTH: { - EdgeProp edgeProp; - edgeProp.set_type(-edgeType); - std::vector props{kSrc, kType, kRank, kDst}; - for (std::size_t i = 0; i < edgeSchema->getNumFields(); ++i) { - props.emplace_back(edgeSchema->getFieldName(i)); - } - edgeProp.set_props(std::move(props)); - edgeProps->emplace_back(std::move(edgeProp)); - break; - } - } - EdgeProp edgeProp; - edgeProp.set_type(edgeType); - std::vector props{kSrc, kType, kRank, kDst}; - for (std::size_t i = 0; i < edgeSchema->getNumFields(); ++i) { - props.emplace_back(edgeSchema->getFieldName(i)); - } - edgeProp.set_props(std::move(props)); - edgeProps->emplace_back(std::move(edgeProp)); - } - return edgeProps; -} - -static Expression* mergePathColumnsExpr(ObjectPool* pool, - const std::string& lcol, - const std::string& rcol) { - auto expr = PathBuildExpression::make(pool); - expr->add(InputPropertyExpression::make(pool, lcol)); - expr->add(InputPropertyExpression::make(pool, rcol)); - return expr; -} - -static Expression* buildPathExpr(ObjectPool* pool) { - auto expr = PathBuildExpression::make(pool); - expr->add(VertexExpression::make(pool)); - expr->add(EdgeExpression::make(pool)); - return expr; -} - -Status Expand::doExpand(const NodeInfo& node, const EdgeInfo& edge, SubPlan* plan) { - NG_RETURN_IF_ERROR(expandSteps(node, edge, plan)); - NG_RETURN_IF_ERROR(filterDatasetByPathLength(edge, plan->root, plan)); - return Status::OK(); -} - -// Build subplan: Project->Dedup->GetNeighbors->[Filter]->Project2-> -// DataJoin->Project3->[Filter]->Passthrough->Loop->UnionAllVer -Status Expand::expandSteps(const NodeInfo& node, const EdgeInfo& edge, SubPlan* plan) { - SubPlan subplan; - int64_t startIndex = 0; - auto minHop = edge.range ? edge.range->min() : 1; - auto maxHop = edge.range ? edge.range->max() : 1; - - // Build first step - // In the case of 0 step, src node is the dst node, return the vertex directly - if (minHop == 0) { - subplan = *plan; - startIndex = 0; - // Get vertex - NG_RETURN_IF_ERROR(MatchSolver::appendFetchVertexPlan( - node.filter, matchCtx_->space, matchCtx_->qctx, &initialExpr_, inputVar_, subplan)); - } else { // Case 1 to n steps - startIndex = 1; - // Expand first step from src - NG_RETURN_IF_ERROR(expandStep(edge, dependency_, inputVar_, node.filter, &subplan)); - } - // No need to further expand if maxHop is the start Index - if (maxHop == startIndex) { - plan->root = subplan.root; - return Status::OK(); - } - // Result of first step expansion - PlanNode* firstStep = subplan.root; - - // Build Start node from first step - SubPlan loopBodyPlan; - PlanNode* startNode = StartNode::make(matchCtx_->qctx); - startNode->setOutputVar(firstStep->outputVar()); - startNode->setColNames(firstStep->colNames()); - loopBodyPlan.tail = startNode; - loopBodyPlan.root = startNode; - - // Construct loop body - NG_RETURN_IF_ERROR(expandStep(edge, - startNode, // dep - startNode->outputVar(), // inputVar - nullptr, - &loopBodyPlan)); - - NG_RETURN_IF_ERROR(collectData(startNode, // left join node - loopBodyPlan.root, // right join node - &firstStep, // passThrough - &subplan)); - // Union node - auto body = subplan.root; - - // Loop condition - auto condition = buildExpandCondition(body->outputVar(), startIndex, maxHop); - - // Create loop - auto* loop = Loop::make(matchCtx_->qctx, firstStep, body, condition); - - // Unionize the results of each expansion which are stored in the firstStep - // node - auto uResNode = UnionAllVersionVar::make(matchCtx_->qctx, loop); - uResNode->setInputVar(firstStep->outputVar()); - uResNode->setColNames({kPathStr}); - - subplan.root = uResNode; - plan->root = subplan.root; - return Status::OK(); -} - -// Build subplan: Project->Dedup->GetNeighbors->[Filter]->Project -Status Expand::expandStep(const EdgeInfo& edge, - PlanNode* dep, - const std::string& inputVar, - const Expression* nodeFilter, - SubPlan* plan) { - auto qctx = matchCtx_->qctx; - auto* pool = qctx->objPool(); - // Extract dst vid from input project node which output dataset format is: - // [v1,e1,...,vn,en] - SubPlan curr; - curr.root = dep; - MatchSolver::extractAndDedupVidColumn(qctx, &initialExpr_, dep, inputVar, curr); - // [GetNeighbors] - auto gn = GetNeighbors::make(qctx, curr.root, matchCtx_->space.id); - auto srcExpr = InputPropertyExpression::make(pool, kVid); - gn->setSrc(srcExpr); - gn->setVertexProps(genVertexProps()); - gn->setEdgeProps(genEdgeProps(edge)); - gn->setEdgeDirection(edge.direction); - - PlanNode* root = gn; - if (nodeFilter != nullptr) { - auto* newFilter = MatchSolver::rewriteLabel2Vertex(qctx, nodeFilter); - auto filterNode = Filter::make(matchCtx_->qctx, root, newFilter); - filterNode->setColNames(root->colNames()); - root = filterNode; - } - - if (edge.filter != nullptr) { - auto* newFilter = MatchSolver::rewriteLabel2Edge(qctx, edge.filter); - auto filterNode = Filter::make(qctx, root, newFilter); - filterNode->setColNames(root->colNames()); - root = filterNode; - } - - auto listColumns = saveObject(new YieldColumns); - listColumns->addColumn(new YieldColumn(buildPathExpr(pool), kPathStr)); - // [Project] - root = Project::make(qctx, root, listColumns); - root->setColNames({kPathStr}); - - plan->root = root; - plan->tail = curr.tail; - return Status::OK(); -} - -// Build subplan: DataJoin->Project->Filter -Status Expand::collectData(const PlanNode* joinLeft, - const PlanNode* joinRight, - PlanNode** passThrough, - SubPlan* plan) { - auto qctx = matchCtx_->qctx; - // [dataJoin] read start node (joinLeft) - auto join = SegmentsConnector::innerJoinSegments(qctx, joinLeft, joinRight); - auto lpath = folly::stringPrintf("%s_%d", kPathStr, 0); - auto rpath = folly::stringPrintf("%s_%d", kPathStr, 1); - join->setColNames({lpath, rpath}); - plan->tail = join; - - auto columns = saveObject(new YieldColumns); - auto listExpr = mergePathColumnsExpr(qctx->objPool(), lpath, rpath); - columns->addColumn(new YieldColumn(listExpr)); - // [Project] - auto project = Project::make(qctx, join, columns); - project->setColNames({kPathStr}); - // [Filter] - auto filter = MatchSolver::filtPathHasSameEdge(project, kPathStr, qctx); - // Update start node - filter->setOutputVar((*passThrough)->outputVar()); - plan->root = filter; - return Status::OK(); -} - -Status Expand::filterDatasetByPathLength(const EdgeInfo& edge, PlanNode* input, SubPlan* plan) { - auto qctx = matchCtx_->qctx; - auto* pool = qctx->objPool(); - - // Filter rows whose edges number less than min hop - auto args = ArgumentList::make(pool); - // Expr: length(relationships(p)) >= minHop - auto pathExpr = InputPropertyExpression::make(pool, kPathStr); - args->addArgument(pathExpr); - auto edgeExpr = FunctionCallExpression::make(pool, "length", args); - auto minHop = edge.range == nullptr ? 1 : edge.range->min(); - auto minHopExpr = ConstantExpression::make(pool, minHop); - auto expr = RelationalExpression::makeGE(pool, edgeExpr, minHopExpr); - - auto filter = Filter::make(qctx, input, expr); - filter->setColNames(input->colNames()); - plan->root = filter; - return Status::OK(); -} - -// loopSteps{startIndex} <= maxHop && ($lastStepResult == empty || -// size($lastStepResult) != 0) -Expression* Expand::buildExpandCondition(const std::string& lastStepResult, - int64_t startIndex, - int64_t maxHop) const { - VLOG(1) << "match expand maxHop: " << maxHop; - auto pool = matchCtx_->qctx->objPool(); - auto loopSteps = matchCtx_->qctx->vctx()->anonVarGen()->getVar(); - matchCtx_->qctx->ectx()->setValue(loopSteps, startIndex); - // ++loopSteps{startIndex} << maxHop - auto stepCondition = ExpressionUtils::stepCondition(pool, loopSteps, maxHop); - // lastStepResult == empty || size(lastStepReult) != 0 - auto* eqEmpty = RelationalExpression::makeEQ(pool, - VariableExpression::make(pool, lastStepResult), - ConstantExpression::make(pool, Value())); - auto neZero = ExpressionUtils::neZeroCondition(pool, lastStepResult); - auto* existValCondition = LogicalExpression::makeOr(pool, eqEmpty, neZero); - return LogicalExpression::makeAnd(pool, stepCondition, existValCondition); -} - -} // namespace graph -} // namespace nebula diff --git a/src/graph/planner/match/Expand.h b/src/graph/planner/match/Expand.h deleted file mode 100644 index 9292173b5d0..00000000000 --- a/src/graph/planner/match/Expand.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2020 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#ifndef GRAPH_PLANNER_MATCH_EXPAND_H_ -#define GRAPH_PLANNER_MATCH_EXPAND_H_ - -#include "common/base/Base.h" -#include "graph/context/ast/CypherAstContext.h" -#include "graph/planner/Planner.h" -#include "graph/planner/plan/PlanNode.h" -#include "graph/util/ExpressionUtils.h" - -namespace nebula { -namespace graph { -/* - * The Expand was designed to handle the pattern expanding. - */ -class Expand final { - public: - Expand(MatchClauseContext* matchCtx, Expression* initialExpr) - : matchCtx_(matchCtx), initialExpr_(initialExpr) {} - - Expand* reversely() { - reversely_ = true; - return this; - } - - Expand* depends(PlanNode* dep) { - dependency_ = dep; - return this; - } - - Expand* inputVar(const std::string& inputVar) { - inputVar_ = inputVar; - return this; - } - - Status doExpand(const NodeInfo& node, const EdgeInfo& edge, SubPlan* plan); - - private: - Status expandSteps(const NodeInfo& node, const EdgeInfo& edge, SubPlan* plan); - - Status expandStep(const EdgeInfo& edge, - PlanNode* dep, - const std::string& inputVar, - const Expression* nodeFilter, - SubPlan* plan); - - Status collectData(const PlanNode* joinLeft, - const PlanNode* joinRight, - PlanNode** passThrough, - SubPlan* plan); - - Status filterDatasetByPathLength(const EdgeInfo& edge, PlanNode* input, SubPlan* plan); - - Expression* buildExpandCondition(const std::string& lastStepResult, - int64_t startIndex, - int64_t maxHop) const; - - template - T* saveObject(T* obj) const { - return matchCtx_->qctx->objPool()->add(obj); - } - - std::unique_ptr> genEdgeProps(const EdgeInfo& edge); - - MatchClauseContext* matchCtx_; - Expression* initialExpr_{nullptr}; - bool reversely_{false}; - PlanNode* dependency_{nullptr}; - std::string inputVar_; -}; -} // namespace graph -} // namespace nebula -#endif // GRAPH_PLANNER_MATCH_EXPAND_H_ diff --git a/src/graph/planner/match/LabelIndexSeek.cpp b/src/graph/planner/match/LabelIndexSeek.cpp index 07187484509..baf9e9266d1 100644 --- a/src/graph/planner/match/LabelIndexSeek.cpp +++ b/src/graph/planner/match/LabelIndexSeek.cpp @@ -17,7 +17,7 @@ bool LabelIndexSeek::matchNode(NodeContext* nodeCtx) { // only require the tag if (node.tids.size() != 1) { // TODO multiple tag index seek need the IndexScan support - VLOG(2) << "Multple tag index seek is not supported now."; + VLOG(2) << "Multiple tag index seek is not supported now."; return false; } @@ -81,7 +81,7 @@ StatusOr LabelIndexSeek::transformNode(NodeContext* nodeCtx) { plan.tail = scan; plan.root = scan; - // This if-block is a patch for or-filter-embeding to avoid OOM, + // This if-block is a patch for or-filter-embedding to avoid OOM, // and it should be converted to an `optRule` after the match validator is // refactored auto& whereCtx = matchClauseCtx->where; @@ -104,19 +104,19 @@ StatusOr LabelIndexSeek::transformNode(NodeContext* nodeCtx) { auto flattenFilter = ExpressionUtils::flattenInnerLogicalExpr(filter); DCHECK_EQ(flattenFilter->kind(), Expression::Kind::kLogicalOr); auto& filterItems = static_cast(flattenFilter)->operands(); - auto canBeEmbeded = [](Expression::Kind k) -> bool { + auto canBeEmbedded = [](Expression::Kind k) -> bool { return k == Expression::Kind::kRelEQ || k == Expression::Kind::kRelLT || k == Expression::Kind::kRelLE || k == Expression::Kind::kRelGT || k == Expression::Kind::kRelGE; }; - bool canBeEmbeded2IndexScan = true; + bool canBeEmbedded2IndexScan = true; for (auto& f : filterItems) { - if (!canBeEmbeded(f->kind())) { - canBeEmbeded2IndexScan = false; + if (!canBeEmbedded(f->kind())) { + canBeEmbedded2IndexScan = false; break; } } - if (canBeEmbeded2IndexScan) { + if (canBeEmbedded2IndexScan) { auto* srcFilter = ExpressionUtils::rewriteLabelAttr2TagProp(flattenFilter); storage::cpp2::IndexQueryContext ctx; ctx.set_filter(Expression::encode(*srcFilter)); @@ -170,21 +170,29 @@ StatusOr LabelIndexSeek::transformEdge(EdgeContext* edgeCtx) { auto* pool = qctx->objPool(); if (edgeCtx->scanInfo.direction == MatchEdge::Direction::BOTH) { - // merge the src,dst to one column - auto* yieldColumns = pool->makeAndAdd(); - auto* exprList = ExpressionList::make(pool); - exprList->add(ColumnExpression::make(pool, 0)); // src - exprList->add(ColumnExpression::make(pool, 1)); // dst - yieldColumns->addColumn(new YieldColumn(ListExpression::make(pool, exprList))); - auto* project = Project::make(qctx, scan, yieldColumns); - project->setColNames({kVid}); - - auto* unwindExpr = ColumnExpression::make(pool, 0); - auto* unwind = Unwind::make(matchClauseCtx->qctx, project, unwindExpr, kVid); - unwind->setColNames({"vidList", kVid}); - plan.root = unwind; + PlanNode* left = nullptr; + { + auto* yieldColumns = pool->makeAndAdd(); + yieldColumns->addColumn(new YieldColumn(InputPropertyExpression::make(pool, kSrc))); + left = Project::make(qctx, scan, yieldColumns); + left->setColNames({kVid}); + } + PlanNode* right = nullptr; + { + auto* yieldColumns = pool->makeAndAdd(); + yieldColumns->addColumn(new YieldColumn(InputPropertyExpression::make(pool, kDst))); + right = Project::make(qctx, scan, yieldColumns); + right->setColNames({kVid}); + } + + plan.root = Union::make(qctx, left, right); + plan.root->setColNames({kVid}); } + auto* dedup = Dedup::make(qctx, plan.root); + dedup->setColNames(plan.root->colNames()); + plan.root = dedup; + // initialize start expression in project node edgeCtx->initialExpr = VariablePropertyExpression::make(pool, "", kVid); return plan; diff --git a/src/graph/planner/match/MatchClausePlanner.cpp b/src/graph/planner/match/MatchClausePlanner.cpp index 4a191ab466f..7ff42c9914b 100644 --- a/src/graph/planner/match/MatchClausePlanner.cpp +++ b/src/graph/planner/match/MatchClausePlanner.cpp @@ -6,19 +6,99 @@ #include "graph/planner/match/MatchClausePlanner.h" #include "graph/context/ast/CypherAstContext.h" -#include "graph/planner/match/Expand.h" #include "graph/planner/match/MatchSolver.h" #include "graph/planner/match/SegmentsConnector.h" #include "graph/planner/match/StartVidFinder.h" #include "graph/planner/match/WhereClausePlanner.h" #include "graph/planner/plan/Query.h" #include "graph/util/ExpressionUtils.h" +#include "graph/util/SchemaUtil.h" #include "graph/visitor/RewriteVisitor.h" using JoinStrategyPos = nebula::graph::InnerJoinStrategy::JoinPos; namespace nebula { namespace graph { +static std::vector genTraverseColNames(const std::vector& inputCols, + const NodeInfo& node, + const EdgeInfo& edge) { + auto cols = inputCols; + cols.emplace_back(node.alias); + cols.emplace_back(edge.alias); + return cols; +} + +static std::vector genAppendVColNames(const std::vector& inputCols, + const NodeInfo& node) { + auto cols = inputCols; + cols.emplace_back(node.alias); + return cols; +} + +static Expression* genNextTraverseStart(ObjectPool* pool, const EdgeInfo& edge) { + auto args = ArgumentList::make(pool); + args->addArgument(InputPropertyExpression::make(pool, edge.alias)); + return FunctionCallExpression::make(pool, "none_direct_dst", args); +} + +static Expression* genVertexFilter(const NodeInfo& node) { return node.filter; } + +static Expression* genEdgeFilter(const EdgeInfo& edge) { return edge.filter; } + +static std::unique_ptr> genVertexProps(const NodeInfo& node, + QueryContext* qctx, + GraphSpaceID spaceId) { + // TODO + UNUSED(node); + UNUSED(qctx); + UNUSED(spaceId); + return std::make_unique>(); +} + +static std::unique_ptr> genEdgeProps(const EdgeInfo& edge, + bool reversely, + QueryContext* qctx, + GraphSpaceID spaceId) { + auto edgeProps = std::make_unique>(); + for (auto edgeType : edge.edgeTypes) { + auto edgeSchema = qctx->schemaMng()->getEdgeSchema(spaceId, edgeType); + + switch (edge.direction) { + case Direction::OUT_EDGE: { + if (reversely) { + edgeType = -edgeType; + } + break; + } + case Direction::IN_EDGE: { + if (!reversely) { + edgeType = -edgeType; + } + break; + } + case Direction::BOTH: { + EdgeProp edgeProp; + edgeProp.set_type(-edgeType); + std::vector props{kSrc, kType, kRank, kDst}; + for (std::size_t i = 0; i < edgeSchema->getNumFields(); ++i) { + props.emplace_back(edgeSchema->getFieldName(i)); + } + edgeProp.set_props(std::move(props)); + edgeProps->emplace_back(std::move(edgeProp)); + break; + } + } + EdgeProp edgeProp; + edgeProp.set_type(edgeType); + std::vector props{kSrc, kType, kRank, kDst}; + for (std::size_t i = 0; i < edgeSchema->getNumFields(); ++i) { + props.emplace_back(edgeSchema->getFieldName(i)); + } + edgeProp.set_props(std::move(props)); + edgeProps->emplace_back(std::move(edgeProp)); + } + return edgeProps; +} StatusOr MatchClausePlanner::transform(CypherClauseContextBase* clauseCtx) { if (clauseCtx->kind != CypherClauseKind::kMatch) { @@ -35,7 +115,7 @@ StatusOr MatchClausePlanner::transform(CypherClauseContextBase* clauseC NG_RETURN_IF_ERROR(findStarts(matchClauseCtx, startFromEdge, startIndex, matchClausePlan)); NG_RETURN_IF_ERROR( expand(nodeInfos, edgeInfos, matchClauseCtx, startFromEdge, startIndex, matchClausePlan)); - NG_RETURN_IF_ERROR(projectColumnsBySymbols(matchClauseCtx, startIndex, matchClausePlan)); + NG_RETURN_IF_ERROR(projectColumnsBySymbols(matchClauseCtx, matchClausePlan)); NG_RETURN_IF_ERROR(appendFilterPlan(matchClauseCtx, matchClausePlan)); return matchClausePlan; } @@ -130,14 +210,9 @@ Status MatchClausePlanner::expandFromNode(const std::vector& nodeInfos // Pattern: ()-[]-...-(start)-...-[]-() NG_RETURN_IF_ERROR( rightExpandFromNode(nodeInfos, edgeInfos, matchClauseCtx, startIndex, subplan)); - auto left = subplan.root; - NG_RETURN_IF_ERROR( - leftExpandFromNode(nodeInfos, edgeInfos, matchClauseCtx, startIndex, var, subplan)); + NG_RETURN_IF_ERROR(leftExpandFromNode( + nodeInfos, edgeInfos, matchClauseCtx, startIndex, subplan.root->outputVar(), subplan)); - // Connect the left expand and right expand part. - auto right = subplan.root; - subplan.root = SegmentsConnector::innerJoinSegments( - matchClauseCtx->qctx, left, right, JoinStrategyPos::kStart, JoinStrategyPos::kStart); return Status::OK(); } @@ -147,48 +222,47 @@ Status MatchClausePlanner::leftExpandFromNode(const std::vector& nodeI size_t startIndex, std::string inputVar, SubPlan& subplan) { - std::vector joinColNames = { - folly::stringPrintf("%s_%lu", kPathStr, nodeInfos.size())}; + Expression* nextTraverseStart = nullptr; + auto qctx = matchClauseCtx->qctx; + if (startIndex == nodeInfos.size() - 1) { + nextTraverseStart = initialExpr_; + } else { + auto* pool = qctx->objPool(); + auto args = ArgumentList::make(pool); + args->addArgument(InputPropertyExpression::make(pool, nodeInfos[startIndex].alias)); + nextTraverseStart = FunctionCallExpression::make(pool, "id", args); + } + auto spaceId = matchClauseCtx->space.id; + bool reversely = true; for (size_t i = startIndex; i > 0; --i) { - auto left = subplan.root; - auto status = - std::make_unique(matchClauseCtx, i == startIndex ? initialExpr_->clone() : nullptr) - ->depends(subplan.root) - ->inputVar(inputVar) - ->reversely() - ->doExpand(nodeInfos[i], edgeInfos[i - 1], &subplan); - if (!status.ok()) { - return status; - } - if (i < startIndex) { - auto right = subplan.root; - VLOG(1) << "left: " << folly::join(",", left->colNames()) - << " right: " << folly::join(",", right->colNames()); - subplan.root = SegmentsConnector::innerJoinSegments(matchClauseCtx->qctx, left, right); - joinColNames.emplace_back(folly::stringPrintf("%s_%lu", kPathStr, nodeInfos.size() + i)); - subplan.root->setColNames(joinColNames); - } - inputVar = subplan.root->outputVar(); + auto& node = nodeInfos[i]; + auto& edge = edgeInfos[i - 1]; + auto traverse = Traverse::make(qctx, subplan.root, spaceId); + traverse->setSrc(nextTraverseStart); + traverse->setVertexProps(genVertexProps(node, qctx, spaceId)); + traverse->setEdgeProps(genEdgeProps(edge, reversely, qctx, spaceId)); + traverse->setVertexFilter(genVertexFilter(node)); + traverse->setEdgeFilter(genEdgeFilter(edge)); + traverse->setEdgeDirection(edge.direction); + traverse->setColNames(genTraverseColNames(subplan.root->colNames(), node, edge)); + traverse->setStepRange(edge.range); + traverse->setDedup(); + subplan.root = traverse; + nextTraverseStart = genNextTraverseStart(qctx->objPool(), edge); + inputVar = traverse->outputVar(); } VLOG(1) << subplan; - auto left = subplan.root; - auto* initialExprCopy = initialExpr_->clone(); - NG_RETURN_IF_ERROR( - MatchSolver::appendFetchVertexPlan(nodeInfos.front().filter, - matchClauseCtx->space, - matchClauseCtx->qctx, - edgeInfos.empty() ? &initialExprCopy : nullptr, - subplan)); - if (!edgeInfos.empty()) { - auto right = subplan.root; - VLOG(1) << "left: " << folly::join(",", left->colNames()) - << " right: " << folly::join(",", right->colNames()); - subplan.root = SegmentsConnector::innerJoinSegments(matchClauseCtx->qctx, left, right); - joinColNames.emplace_back( - folly::stringPrintf("%s_%lu", kPathStr, nodeInfos.size() + startIndex)); - subplan.root->setColNames(joinColNames); - } + auto& node = nodeInfos.front(); + auto appendV = AppendVertices::make(qctx, subplan.root, spaceId); + auto vertexProps = SchemaUtil::getAllVertexProp(qctx, spaceId, true); + NG_RETURN_IF_ERROR(vertexProps); + appendV->setVertexProps(std::move(vertexProps).value()); + appendV->setSrc(nextTraverseStart); + appendV->setVertexFilter(genVertexFilter(node)); + appendV->setColNames(genAppendVColNames(subplan.root->colNames(), node)); + appendV->setDedup(); + subplan.root = appendV; VLOG(1) << subplan; return Status::OK(); @@ -199,44 +273,40 @@ Status MatchClausePlanner::rightExpandFromNode(const std::vector& node MatchClauseContext* matchClauseCtx, size_t startIndex, SubPlan& subplan) { - std::vector joinColNames = {folly::stringPrintf("%s_%lu", kPathStr, startIndex)}; + auto inputVar = subplan.root->outputVar(); + auto qctx = matchClauseCtx->qctx; + auto spaceId = matchClauseCtx->space.id; + Expression* nextTraverseStart = initialExpr_; + bool reversely = false; for (size_t i = startIndex; i < edgeInfos.size(); ++i) { - auto left = subplan.root; - auto status = - std::make_unique(matchClauseCtx, i == startIndex ? initialExpr_->clone() : nullptr) - ->depends(subplan.root) - ->inputVar(subplan.root->outputVar()) - ->doExpand(nodeInfos[i], edgeInfos[i], &subplan); - if (!status.ok()) { - return status; - } - if (i > startIndex) { - auto right = subplan.root; - VLOG(1) << "left: " << folly::join(",", left->colNames()) - << " right: " << folly::join(",", right->colNames()); - subplan.root = SegmentsConnector::innerJoinSegments(matchClauseCtx->qctx, left, right); - joinColNames.emplace_back(folly::stringPrintf("%s_%lu", kPathStr, i)); - subplan.root->setColNames(joinColNames); - } + auto& node = nodeInfos[i]; + auto& edge = edgeInfos[i]; + auto traverse = Traverse::make(qctx, subplan.root, spaceId); + traverse->setSrc(nextTraverseStart); + traverse->setVertexProps(genVertexProps(node, qctx, spaceId)); + traverse->setEdgeProps(genEdgeProps(edge, reversely, qctx, spaceId)); + traverse->setVertexFilter(genVertexFilter(node)); + traverse->setEdgeFilter(genEdgeFilter(edge)); + traverse->setEdgeDirection(edge.direction); + traverse->setColNames(genTraverseColNames(subplan.root->colNames(), node, edge)); + traverse->setStepRange(edge.range); + traverse->setDedup(); + subplan.root = traverse; + nextTraverseStart = genNextTraverseStart(qctx->objPool(), edge); + inputVar = traverse->outputVar(); } VLOG(1) << subplan; - auto left = subplan.root; - auto* initialExprCopy = initialExpr_->clone(); - NG_RETURN_IF_ERROR( - MatchSolver::appendFetchVertexPlan(nodeInfos.back().filter, - matchClauseCtx->space, - matchClauseCtx->qctx, - edgeInfos.empty() ? &initialExprCopy : nullptr, - subplan)); - if (!edgeInfos.empty()) { - auto right = subplan.root; - VLOG(1) << "left: " << folly::join(",", left->colNames()) - << " right: " << folly::join(",", right->colNames()); - subplan.root = SegmentsConnector::innerJoinSegments(matchClauseCtx->qctx, left, right); - joinColNames.emplace_back(folly::stringPrintf("%s_%lu", kPathStr, edgeInfos.size())); - subplan.root->setColNames(joinColNames); - } + auto& node = nodeInfos.back(); + auto appendV = AppendVertices::make(qctx, subplan.root, spaceId); + auto vertexProps = SchemaUtil::getAllVertexProp(qctx, spaceId, true); + NG_RETURN_IF_ERROR(vertexProps); + appendV->setVertexProps(std::move(vertexProps).value()); + appendV->setSrc(nextTraverseStart); + appendV->setVertexFilter(genVertexFilter(node)); + appendV->setColNames(genAppendVColNames(subplan.root->colNames(), node)); + appendV->setDedup(); + subplan.root = appendV; VLOG(1) << subplan; return Status::OK(); @@ -251,146 +321,80 @@ Status MatchClausePlanner::expandFromEdge(const std::vector& nodeInfos } Status MatchClausePlanner::projectColumnsBySymbols(MatchClauseContext* matchClauseCtx, - size_t startIndex, SubPlan& plan) { auto qctx = matchClauseCtx->qctx; auto& nodeInfos = matchClauseCtx->nodeInfos; auto& edgeInfos = matchClauseCtx->edgeInfos; - auto input = plan.root; - const auto& inColNames = input->colNames(); auto columns = qctx->objPool()->add(new YieldColumns); std::vector colNames; - auto addNode = [&, this](size_t i) { - auto& nodeInfo = nodeInfos[i]; + auto addNode = [this, columns, &colNames, matchClauseCtx](auto& nodeInfo) { if (!nodeInfo.alias.empty() && !nodeInfo.anonymous) { - if (i >= startIndex) { - columns->addColumn( - buildVertexColumn(matchClauseCtx, inColNames[i - startIndex], nodeInfo.alias)); - } else if (startIndex == (nodeInfos.size() - 1)) { - columns->addColumn( - buildVertexColumn(matchClauseCtx, inColNames[startIndex - i], nodeInfo.alias)); - } else { - columns->addColumn( - buildVertexColumn(matchClauseCtx, inColNames[nodeInfos.size() - i], nodeInfo.alias)); - } + columns->addColumn(buildVertexColumn(matchClauseCtx, nodeInfo.alias)); colNames.emplace_back(nodeInfo.alias); } }; - for (size_t i = 0; i < edgeInfos.size(); i++) { - VLOG(1) << "colSize: " << inColNames.size() << "i: " << i << " nodesize: " << nodeInfos.size() - << " start: " << startIndex; - addNode(i); - auto& edgeInfo = edgeInfos[i]; + auto addEdge = [this, columns, &colNames, matchClauseCtx](auto& edgeInfo) { if (!edgeInfo.alias.empty() && !edgeInfo.anonymous) { - if (i >= startIndex) { - columns->addColumn(buildEdgeColumn(matchClauseCtx, inColNames[i - startIndex], edgeInfo)); - } else if (startIndex == (nodeInfos.size() - 1)) { - columns->addColumn( - buildEdgeColumn(matchClauseCtx, inColNames[edgeInfos.size() - 1 - i], edgeInfo)); - } else { - columns->addColumn( - buildEdgeColumn(matchClauseCtx, inColNames[edgeInfos.size() - i], edgeInfo)); - } + columns->addColumn(buildEdgeColumn(matchClauseCtx, edgeInfo)); colNames.emplace_back(edgeInfo.alias); } + }; + + for (size_t i = 0; i < edgeInfos.size(); i++) { + addNode(nodeInfos[i]); + addEdge(edgeInfos[i]); } // last vertex DCHECK(!nodeInfos.empty()); - addNode(nodeInfos.size() - 1); + addNode(nodeInfos.back()); const auto& aliases = matchClauseCtx->aliasesGenerated; auto iter = std::find_if(aliases.begin(), aliases.end(), [](const auto& alias) { return alias.second == AliasType::kPath; }); - std::string alias = iter != aliases.end() ? iter->first : qctx->vctx()->anonColGen()->getCol(); - columns->addColumn( - buildPathColumn(matchClauseCtx, alias, startIndex, inColNames, nodeInfos.size())); - colNames.emplace_back(alias); + if (iter != aliases.end()) { + auto& alias = iter->first; + columns->addColumn(buildPathColumn(matchClauseCtx, alias)); + colNames.emplace_back(alias); + } - auto project = Project::make(qctx, input, columns); + auto project = Project::make(qctx, plan.root, columns); project->setColNames(std::move(colNames)); - plan.root = MatchSolver::filtPathHasSameEdge(project, alias, qctx); + plan.root = project; VLOG(1) << plan; return Status::OK(); } YieldColumn* MatchClausePlanner::buildVertexColumn(MatchClauseContext* matchClauseCtx, - const std::string& colName, const std::string& alias) const { - auto* pool = matchClauseCtx->qctx->objPool(); - auto colExpr = InputPropertyExpression::make(pool, colName); - // startNode(path) => head node of path - auto args = ArgumentList::make(pool); - args->addArgument(colExpr); - auto firstVertexExpr = FunctionCallExpression::make(pool, "startNode", args); - return new YieldColumn(firstVertexExpr, alias); + return new YieldColumn(InputPropertyExpression::make(matchClauseCtx->qctx->objPool(), alias), + alias); } YieldColumn* MatchClausePlanner::buildEdgeColumn(MatchClauseContext* matchClauseCtx, - const std::string& colName, EdgeInfo& edge) const { auto* pool = matchClauseCtx->qctx->objPool(); - auto colExpr = InputPropertyExpression::make(pool, colName); - // relationships(p) - auto args = ArgumentList::make(pool); - args->addArgument(colExpr); - auto relExpr = FunctionCallExpression::make(pool, "relationships", args); Expression* expr = nullptr; - if (edge.range != nullptr) { - expr = relExpr; + if (edge.range == nullptr) { + expr = SubscriptExpression::make( + pool, InputPropertyExpression::make(pool, edge.alias), ConstantExpression::make(pool, 0)); } else { - // Get first edge in path list [e1, e2, ...] - auto idxExpr = ConstantExpression::make(pool, 0); - auto subExpr = SubscriptExpression::make(pool, relExpr, idxExpr); - expr = subExpr; + auto* args = ArgumentList::make(pool); + args->addArgument(VariableExpression::make(pool, "e")); + auto* filter = FunctionCallExpression::make(pool, "is_edge", args); + expr = ListComprehensionExpression::make( + pool, "e", InputPropertyExpression::make(pool, edge.alias), filter); } return new YieldColumn(expr, edge.alias); } YieldColumn* MatchClausePlanner::buildPathColumn(MatchClauseContext* matchClauseCtx, - const std::string& alias, - size_t startIndex, - const std::vector colNames, - size_t nodeInfoSize) const { - auto colSize = colNames.size(); - DCHECK((nodeInfoSize == colSize) || (nodeInfoSize + 1 == colSize)); - size_t bound = 0; - if (colSize > nodeInfoSize) { - bound = colSize - startIndex - 1; - } else if (startIndex == (nodeInfoSize - 1)) { - bound = 0; - } else { - bound = colSize - startIndex; - } - auto* pool = matchClauseCtx->qctx->objPool(); - auto rightExpandPath = PathBuildExpression::make(pool); - for (size_t i = 0; i < bound; ++i) { - rightExpandPath->add(InputPropertyExpression::make(pool, colNames[i])); - } - - auto leftExpandPath = PathBuildExpression::make(pool); - for (size_t i = bound; i < colNames.size(); ++i) { - leftExpandPath->add(InputPropertyExpression::make(pool, colNames[i])); - } - - auto finalPath = PathBuildExpression::make(pool); - if (leftExpandPath->size() != 0) { - auto args = ArgumentList::make(pool); - args->addArgument(leftExpandPath); - auto reversePath = FunctionCallExpression::make(pool, "reversePath", args); - if (rightExpandPath->size() == 0) { - return new YieldColumn(reversePath, alias); - } - finalPath->add(reversePath); - } - if (rightExpandPath->size() != 0) { - finalPath->add(rightExpandPath); - } - return new YieldColumn(finalPath, alias); + const std::string& alias) const { + return new YieldColumn(matchClauseCtx->pathBuild, alias); } Status MatchClausePlanner::appendFilterPlan(MatchClauseContext* matchClauseCtx, SubPlan& subplan) { diff --git a/src/graph/planner/match/MatchClausePlanner.h b/src/graph/planner/match/MatchClausePlanner.h index 151e774a27a..19b7c860701 100644 --- a/src/graph/planner/match/MatchClausePlanner.h +++ b/src/graph/planner/match/MatchClausePlanner.h @@ -59,23 +59,14 @@ class MatchClausePlanner final : public CypherClausePlanner { size_t startIndex, SubPlan& subplan); - Status projectColumnsBySymbols(MatchClauseContext* matchClauseCtx, - size_t startIndex, - SubPlan& plan); + Status projectColumnsBySymbols(MatchClauseContext* matchClauseCtx, SubPlan& plan); YieldColumn* buildVertexColumn(MatchClauseContext* matchClauseCtx, - const std::string& colName, const std::string& alias) const; - YieldColumn* buildEdgeColumn(MatchClauseContext* matchClauseCtx, - const std::string& colName, - EdgeInfo& edge) const; + YieldColumn* buildEdgeColumn(MatchClauseContext* matchClauseCtx, EdgeInfo& edge) const; - YieldColumn* buildPathColumn(MatchClauseContext* matchClauseCtx, - const std::string& alias, - size_t startIndex, - const std::vector colNames, - size_t nodeInfoSize) const; + YieldColumn* buildPathColumn(MatchClauseContext* matchClauseCtx, const std::string& alias) const; Status appendFilterPlan(MatchClauseContext* matchClauseCtx, SubPlan& subplan); diff --git a/src/graph/planner/match/MatchSolver.cpp b/src/graph/planner/match/MatchSolver.cpp index b66ec18312e..825eb2ad1ab 100644 --- a/src/graph/planner/match/MatchSolver.cpp +++ b/src/graph/planner/match/MatchSolver.cpp @@ -143,7 +143,7 @@ Expression* MatchSolver::makeIndexFilter(const std::string& label, auto* right = binary->right(); const LabelAttributeExpression* la = nullptr; const ConstantExpression* constant = nullptr; - // TODO(aiee) extract the logic that apllies to both match and lookup + // TODO(aiee) extract the logic that applies to both match and lookup if (left->kind() == Expression::Kind::kLabelAttribute && right->kind() == Expression::Kind::kConstant) { la = static_cast(left); @@ -276,7 +276,7 @@ Status MatchSolver::appendFetchVertexPlan(const Expression* nodeFilter, extractAndDedupVidColumn(qctx, initialExpr, plan.root, inputVar, plan); auto srcExpr = InputPropertyExpression::make(pool, kVid); // [Get vertices] - auto props = SchemaUtil::getAllVertexProp(qctx, space, true); + auto props = SchemaUtil::getAllVertexProp(qctx, space.id, true); NG_RETURN_IF_ERROR(props); auto gv = GetVertices::make(qctx, plan.root, space.id, srcExpr, std::move(props).value(), {}); diff --git a/src/graph/planner/match/PropIndexSeek.cpp b/src/graph/planner/match/PropIndexSeek.cpp index e1c2d47b785..dfbd33f39c5 100644 --- a/src/graph/planner/match/PropIndexSeek.cpp +++ b/src/graph/planner/match/PropIndexSeek.cpp @@ -89,21 +89,29 @@ StatusOr PropIndexSeek::transformEdge(EdgeContext* edgeCtx) { auto* pool = qctx->objPool(); if (edgeCtx->scanInfo.direction == MatchEdge::Direction::BOTH) { - // merge the src,dst to one column - auto* yieldColumns = pool->makeAndAdd(); - auto* exprList = ExpressionList::make(pool); - exprList->add(ColumnExpression::make(pool, 0)); // src - exprList->add(ColumnExpression::make(pool, 1)); // dst - yieldColumns->addColumn(new YieldColumn(ListExpression::make(pool, exprList))); - auto* project = Project::make(qctx, scan, yieldColumns); - project->setColNames({kVid}); - - auto* unwindExpr = ColumnExpression::make(pool, 0); - auto* unwind = Unwind::make(qctx, project, unwindExpr, kVid); - unwind->setColNames({"vidList", kVid}); - plan.root = unwind; + PlanNode* left = nullptr; + { + auto* yieldColumns = pool->makeAndAdd(); + yieldColumns->addColumn(new YieldColumn(InputPropertyExpression::make(pool, kSrc))); + left = Project::make(qctx, scan, yieldColumns); + left->setColNames({kVid}); + } + PlanNode* right = nullptr; + { + auto* yieldColumns = pool->makeAndAdd(); + yieldColumns->addColumn(new YieldColumn(InputPropertyExpression::make(pool, kDst))); + right = Project::make(qctx, scan, yieldColumns); + right->setColNames({kVid}); + } + + plan.root = Union::make(qctx, left, right); + plan.root->setColNames({kVid}); } + auto* dedup = Dedup::make(qctx, plan.root); + dedup->setColNames(plan.root->colNames()); + plan.root = dedup; + // initialize start expression in project edge edgeCtx->initialExpr = VariablePropertyExpression::make(pool, "", kVid); return plan; @@ -113,7 +121,7 @@ bool PropIndexSeek::matchNode(NodeContext* nodeCtx) { auto& node = *nodeCtx->info; if (node.labels.size() != 1) { // TODO multiple tag index seek need the IndexScan support - VLOG(2) << "Multple tag index seek is not supported now."; + VLOG(2) << "Multiple tag index seek is not supported now."; return false; } diff --git a/src/graph/planner/match/VertexIdSeek.cpp b/src/graph/planner/match/VertexIdSeek.cpp index 1b27b877319..9d0df2a085d 100644 --- a/src/graph/planner/match/VertexIdSeek.cpp +++ b/src/graph/planner/match/VertexIdSeek.cpp @@ -7,6 +7,7 @@ #include "graph/planner/match/MatchSolver.h" #include "graph/planner/plan/Logic.h" +#include "graph/planner/plan/Query.h" #include "graph/util/ExpressionUtils.h" #include "graph/util/SchemaUtil.h" #include "graph/visitor/VidExtractVisitor.h" @@ -53,34 +54,16 @@ bool VertexIdSeek::matchNode(NodeContext *nodeCtx) { return false; } -std::pair VertexIdSeek::listToAnnoVarVid(QueryContext *qctx, - const List &list) { +std::string VertexIdSeek::listToAnnoVarVid(QueryContext *qctx, const List &list) { auto input = qctx->vctx()->anonVarGen()->getVar(); DataSet vids({kVid}); - QueryExpressionContext dummy; for (auto &v : list.values) { vids.emplace_back(Row({std::move(v)})); } qctx->ectx()->setResult(input, ResultBuilder().value(Value(std::move(vids))).build()); - auto *pool = qctx->objPool(); - auto *src = VariablePropertyExpression::make(pool, input, kVid); - return std::pair(input, src); -} - -std::pair VertexIdSeek::constToAnnoVarVid(QueryContext *qctx, - const Value &v) { - auto input = qctx->vctx()->anonVarGen()->getVar(); - DataSet vids({kVid}); - QueryExpressionContext dummy; - vids.emplace_back(Row({v})); - - qctx->ectx()->setResult(input, ResultBuilder().value(Value(std::move(vids))).build()); - - auto *pool = qctx->objPool(); - auto *src = VariablePropertyExpression::make(pool, input, kVid); - return std::pair(input, src); + return input; } StatusOr VertexIdSeek::transformNode(NodeContext *nodeCtx) { @@ -88,16 +71,19 @@ StatusOr VertexIdSeek::transformNode(NodeContext *nodeCtx) { auto *matchClauseCtx = nodeCtx->matchClauseCtx; auto *qctx = matchClauseCtx->qctx; - QueryExpressionContext dummy; - std::pair vidsResult = listToAnnoVarVid(qctx, nodeCtx->ids); + std::string inputVar = listToAnnoVarVid(qctx, nodeCtx->ids); auto *passThrough = PassThroughNode::make(qctx, nullptr); - passThrough->setOutputVar(vidsResult.first); + passThrough->setOutputVar(inputVar); passThrough->setColNames({kVid}); - plan.root = passThrough; + + auto *dedup = Dedup::make(qctx, passThrough); + dedup->setColNames({kVid}); + + plan.root = dedup; plan.tail = passThrough; - nodeCtx->initialExpr = vidsResult.second; + nodeCtx->initialExpr = InputPropertyExpression::make(qctx->objPool(), kVid); return plan; } diff --git a/src/graph/planner/match/VertexIdSeek.h b/src/graph/planner/match/VertexIdSeek.h index 891b3b2b8c6..2fd58a172aa 100644 --- a/src/graph/planner/match/VertexIdSeek.h +++ b/src/graph/planner/match/VertexIdSeek.h @@ -31,9 +31,7 @@ class VertexIdSeek final : public StartVidFinder { StatusOr transformEdge(EdgeContext* edgeCtx) override; - std::pair listToAnnoVarVid(QueryContext* qctx, const List& list); - - std::pair constToAnnoVarVid(QueryContext* qctx, const Value& v); + std::string listToAnnoVarVid(QueryContext* qctx, const List& list); private: VertexIdSeek() = default; diff --git a/src/graph/planner/ngql/PathPlanner.cpp b/src/graph/planner/ngql/PathPlanner.cpp index 00b683627e6..f6f7843788c 100644 --- a/src/graph/planner/ngql/PathPlanner.cpp +++ b/src/graph/planner/ngql/PathPlanner.cpp @@ -409,7 +409,7 @@ PlanNode* PathPlanner::buildVertexPlan(PlanNode* dep, const std::string& input) idArgs->addArgument(ColumnExpression::make(pool, 1)); auto* src = FunctionCallExpression::make(pool, "id", idArgs); // get all vertexprop - auto vertexProp = SchemaUtil::getAllVertexProp(qctx, pathCtx_->space, true); + auto vertexProp = SchemaUtil::getAllVertexProp(qctx, pathCtx_->space.id, true); auto* getVertices = GetVertices::make( qctx, unwind, pathCtx_->space.id, src, std::move(vertexProp).value(), {}, true); diff --git a/src/graph/planner/ngql/SubgraphPlanner.cpp b/src/graph/planner/ngql/SubgraphPlanner.cpp index 339724b15bd..ce7a583701c 100644 --- a/src/graph/planner/ngql/SubgraphPlanner.cpp +++ b/src/graph/planner/ngql/SubgraphPlanner.cpp @@ -55,7 +55,7 @@ StatusOr SubgraphPlanner::nSteps(SubPlan& startVidPlan, const std::stri auto* startNode = StartNode::make(qctx); bool getVertexProp = subgraphCtx_->withProp && subgraphCtx_->getVertexProp; - auto vertexProps = SchemaUtil::getAllVertexProp(qctx, space, getVertexProp); + auto vertexProps = SchemaUtil::getAllVertexProp(qctx, space.id, getVertexProp); NG_RETURN_IF_ERROR(vertexProps); auto edgeProps = buildEdgeProps(); NG_RETURN_IF_ERROR(edgeProps); @@ -93,7 +93,7 @@ StatusOr SubgraphPlanner::zeroStep(SubPlan& startVidPlan, const std::st const auto& space = subgraphCtx_->space; auto* pool = qctx->objPool(); // get all vertexProp - auto vertexProp = SchemaUtil::getAllVertexProp(qctx, space, subgraphCtx_->withProp); + auto vertexProp = SchemaUtil::getAllVertexProp(qctx, space.id, subgraphCtx_->withProp); NG_RETURN_IF_ERROR(vertexProp); auto* getVertex = GetVertices::make(qctx, startVidPlan.root, diff --git a/src/graph/planner/plan/Admin.h b/src/graph/planner/plan/Admin.h index 86641dd8110..a8313c5fd68 100644 --- a/src/graph/planner/plan/Admin.h +++ b/src/graph/planner/plan/Admin.h @@ -313,7 +313,7 @@ class DropSnapshot final : public SingleDependencyNode { std::unique_ptr explain() const override; - const std::string& getShapshotName() const { return snapshotName_; } + const std::string& getSnapshotName() const { return snapshotName_; } private: explicit DropSnapshot(QueryContext* qctx, PlanNode* input, std::string snapshotName) diff --git a/src/graph/planner/plan/PlanNode.cpp b/src/graph/planner/plan/PlanNode.cpp index 98e892bb833..4b663865702 100644 --- a/src/graph/planner/plan/PlanNode.cpp +++ b/src/graph/planner/plan/PlanNode.cpp @@ -32,7 +32,7 @@ PlanNode::PlanNode(QueryContext* qctx, Kind kind) : qctx_(qctx), kind_(kind) { const char* PlanNode::toString(PlanNode::Kind kind) { switch (kind) { case Kind::kUnknown: - return "Unkonwn"; + return "Unknown"; case Kind::kStart: return "Start"; case Kind::kGetNeighbors: @@ -278,7 +278,6 @@ const char* PlanNode::toString(PlanNode::Kind kind) { return "Download"; case Kind::kIngest: return "Ingest"; - // no default so the compiler will warning when lack case Kind::kShowSessions: return "ShowSessions"; case Kind::kUpdateSession: @@ -287,6 +286,10 @@ const char* PlanNode::toString(PlanNode::Kind kind) { return "ShowQueries"; case Kind::kKillQuery: return "KillQuery"; + case Kind::kTraverse: + return "Traverse"; + case Kind::kAppendVertices: + return "AppendVertices"; // no default so the compiler will warning when lack } LOG(FATAL) << "Impossible kind plan node " << static_cast(kind); diff --git a/src/graph/planner/plan/PlanNode.h b/src/graph/planner/plan/PlanNode.h index 0f19c866f67..3da8520d477 100644 --- a/src/graph/planner/plan/PlanNode.h +++ b/src/graph/planner/plan/PlanNode.h @@ -27,6 +27,9 @@ class PlanNode { kGetNeighbors, kGetVertices, kGetEdges, + kTraverse, + kAppendVertices, + // ------------------ // TODO(yee): refactor in logical plan kIndexScan, @@ -269,7 +272,7 @@ std::ostream& operator<<(std::ostream& os, PlanNode::Kind kind); // Dependencies will cover the inputs, For example bi input require bi // dependencies as least, but single dependencies may don't need any inputs (I.E -// admin plan node) Single dependecy without input It's useful for admin plan +// admin plan node) Single dependency without input It's useful for admin plan // node class SingleDependencyNode : public PlanNode { public: diff --git a/src/graph/planner/plan/Query.cpp b/src/graph/planner/plan/Query.cpp index 07954678eee..988f8b33245 100644 --- a/src/graph/planner/plan/Query.cpp +++ b/src/graph/planner/plan/Query.cpp @@ -601,5 +601,52 @@ void UnionAllVersionVar::cloneMembers(const UnionAllVersionVar& f) { SingleInputNode::cloneMembers(f); } +Traverse* Traverse::clone() const { + auto newGN = Traverse::make(qctx_, nullptr, space_); + newGN->cloneMembers(*this); + return newGN; +} + +void Traverse::cloneMembers(const Traverse& g) { + GetNeighbors::cloneMembers(g); + + setStepRange(g.range_); + setVertexFilter(g.vFilter_->clone()); + setEdgeFilter(g.eFilter_->clone()); +} + +std::unique_ptr Traverse::explain() const { + auto desc = GetNeighbors::explain(); + if (range_ != nullptr) { + addDescription("steps", range_->toString(), desc.get()); + } + if (vFilter_ != nullptr) { + addDescription("vertex filter", vFilter_->toString(), desc.get()); + } + if (eFilter_ != nullptr) { + addDescription("edge filter", eFilter_->toString(), desc.get()); + } + return desc; +} + +AppendVertices* AppendVertices::clone() const { + auto newAV = AppendVertices::make(qctx_, nullptr, space_); + newAV->cloneMembers(*this); + return newAV; +} + +void AppendVertices::cloneMembers(const AppendVertices& a) { + GetVertices::cloneMembers(a); + + setVertexFilter(a.vFilter_->clone()); +} + +std::unique_ptr AppendVertices::explain() const { + auto desc = GetVertices::explain(); + if (vFilter_ != nullptr) { + addDescription("vertex filter", vFilter_->toString(), desc.get()); + } + return desc; +} } // namespace graph } // namespace nebula diff --git a/src/graph/planner/plan/Query.h b/src/graph/planner/plan/Query.h index b62622bb0e4..2f74d3883d7 100644 --- a/src/graph/planner/plan/Query.h +++ b/src/graph/planner/plan/Query.h @@ -20,7 +20,7 @@ namespace nebula { namespace graph { /** - * Now we hava four kind of exploration nodes: + * Now we have four kind of exploration nodes: * GetNeighbors, * GetVertices, * GetEdges, @@ -120,10 +120,10 @@ using Direction = nebula::storage::cpp2::EdgeDirection; /** * Get neighbors' property */ -class GetNeighbors final : public Explore { +class GetNeighbors : public Explore { public: static GetNeighbors* make(QueryContext* qctx, PlanNode* input, GraphSpaceID space) { - return qctx->objPool()->add(new GetNeighbors(qctx, input, space)); + return qctx->objPool()->add(new GetNeighbors(qctx, Kind::kGetNeighbors, input, space)); } static GetNeighbors* make(QueryContext* qctx, @@ -198,15 +198,15 @@ class GetNeighbors final : public Explore { PlanNode* clone() const override; std::unique_ptr explain() const override; - private: - GetNeighbors(QueryContext* qctx, PlanNode* input, GraphSpaceID space) - : Explore(qctx, Kind::kGetNeighbors, input, space) { + protected: + GetNeighbors(QueryContext* qctx, Kind kind, PlanNode* input, GraphSpaceID space) + : Explore(qctx, kind, input, space) { setLimit(-1); } - private: void cloneMembers(const GetNeighbors&); + private: Expression* src_{nullptr}; std::vector edgeTypes_; storage::cpp2::EdgeDirection edgeDirection_{Direction::OUT_EDGE}; @@ -220,7 +220,7 @@ class GetNeighbors final : public Explore { /** * Get property with given vertex keys. */ -class GetVertices final : public Explore { +class GetVertices : public Explore { public: static GetVertices* make(QueryContext* qctx, PlanNode* input, @@ -233,6 +233,7 @@ class GetVertices final : public Explore { int64_t limit = std::numeric_limits::max(), Expression* filter = nullptr) { return qctx->objPool()->add(new GetVertices(qctx, + Kind::kGetVertices, input, space, src, @@ -259,8 +260,9 @@ class GetVertices final : public Explore { PlanNode* clone() const override; std::unique_ptr explain() const override; - private: + protected: GetVertices(QueryContext* qctx, + Kind kind, PlanNode* input, GraphSpaceID space, Expression* src, @@ -270,7 +272,7 @@ class GetVertices final : public Explore { std::vector orderBy, int64_t limit, Expression* filter) - : Explore(qctx, Kind::kGetVertices, input, space, dedup, limit, filter, std::move(orderBy)), + : Explore(qctx, kind, input, space, dedup, limit, filter, std::move(orderBy)), src_(src), props_(std::move(props)), exprs_(std::move(exprs)) {} @@ -1146,6 +1148,110 @@ class UnionAllVersionVar final : public SingleInputNode { void cloneMembers(const UnionAllVersionVar&); }; +class Traverse final : public GetNeighbors { + public: + using VertexProps = std::unique_ptr>; + using EdgeProps = std::unique_ptr>; + using StatProps = std::unique_ptr>; + using Exprs = std::unique_ptr>; + + static Traverse* make(QueryContext* qctx, PlanNode* input, GraphSpaceID space) { + return qctx->objPool()->add(new Traverse(qctx, input, space)); + } + + static Traverse* make(QueryContext* qctx, + PlanNode* input, + GraphSpaceID space, + Expression* src, + std::vector edgeTypes, + storage::cpp2::EdgeDirection edgeDirection, + VertexProps&& vertexProps, + EdgeProps&& edgeProps, + StatProps&& statProps, + Exprs&& exprs, + bool dedup = false, + bool random = false, + std::vector orderBy = {}, + int64_t limit = -1, + Expression* filter = nullptr) { + auto traverse = make(qctx, input, space); + traverse->setSrc(src); + traverse->setEdgeTypes(std::move(edgeTypes)); + traverse->setEdgeDirection(edgeDirection); + traverse->setVertexProps(std::move(vertexProps)); + traverse->setEdgeProps(std::move(edgeProps)); + traverse->setExprs(std::move(exprs)); + traverse->setStatProps(std::move(statProps)); + traverse->setRandom(random); + traverse->setDedup(dedup); + traverse->setOrderBy(std::move(orderBy)); + traverse->setLimit(limit); + traverse->setFilter(std::move(filter)); + return traverse; + } + + std::unique_ptr explain() const override; + + Traverse* clone() const override; + + MatchStepRange* stepRange() const { return range_; } + + Expression* vFilter() const { return vFilter_; } + + Expression* eFilter() const { return eFilter_; } + + void setStepRange(MatchStepRange* range) { range_ = range; } + + void setVertexFilter(Expression* vFilter) { vFilter_ = vFilter; } + + void setEdgeFilter(Expression* eFilter) { eFilter_ = eFilter; } + + private: + Traverse(QueryContext* qctx, PlanNode* input, GraphSpaceID space) + : GetNeighbors(qctx, Kind::kTraverse, input, space) { + setLimit(-1); + } + + private: + void cloneMembers(const Traverse& g); + + MatchStepRange* range_{nullptr}; + Expression* vFilter_{nullptr}; + Expression* eFilter_{nullptr}; +}; + +class AppendVertices final : public GetVertices { + public: + static AppendVertices* make(QueryContext* qctx, PlanNode* input, GraphSpaceID space) { + return qctx->objPool()->add(new AppendVertices(qctx, input, space)); + } + + std::unique_ptr explain() const override; + + AppendVertices* clone() const override; + + Expression* vFilter() const { return vFilter_; } + + void setVertexFilter(Expression* vFilter) { vFilter_ = vFilter; } + + private: + AppendVertices(QueryContext* qctx, PlanNode* input, GraphSpaceID space) + : GetVertices(qctx, + Kind::kAppendVertices, + input, + space, + nullptr, + nullptr, + nullptr, + false, + {}, + 0, + nullptr) {} + + void cloneMembers(const AppendVertices& a); + + Expression* vFilter_; +}; } // namespace graph } // namespace nebula #endif // GRAPH_PLANNER_PLAN_QUERY_H_ diff --git a/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.h b/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.h index 90ba9a657d9..4610a5cd15e 100644 --- a/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.h +++ b/src/graph/scheduler/AsyncMsgNotifyBasedScheduler.h @@ -13,7 +13,7 @@ namespace nebula { namespace graph { /** - * This is an scheluder implementation based on asynchronous message + * This is an scheduler implementation based on asynchronous message * notification and bread first search. Each node in execution plan would be * triggered to run when the node itself receives all the messages that send by * its dependencies. And once the node is done running, it will send a message diff --git a/src/graph/service/GraphFlags.cpp b/src/graph/service/GraphFlags.cpp index af8e641e478..c95272d563e 100644 --- a/src/graph/service/GraphFlags.cpp +++ b/src/graph/service/GraphFlags.cpp @@ -68,6 +68,6 @@ DEFINE_bool(enable_experimental_feature, false, "Whether to enable experimental DEFINE_bool(enable_client_white_list, true, "Turn on/off the client white list."); DEFINE_string(client_white_list, nebula::getOriginVersion() + ":2.5.0:2.5.1:2.6.0", - "A white list for different client versions, seperate with colon."); + "A white list for different client versions, separate with colon."); DEFINE_int32(num_rows_to_check_memory, 1024, "number rows to check memory"); diff --git a/src/graph/service/QueryEngine.cpp b/src/graph/service/QueryEngine.cpp index 4fcc8d78608..b5d47df8e3a 100644 --- a/src/graph/service/QueryEngine.cpp +++ b/src/graph/service/QueryEngine.cpp @@ -32,7 +32,7 @@ Status QueryEngine::init(std::shared_ptr ioExecutor storage_ = std::make_unique(ioExecutor, metaClient_); charsetInfo_ = CharsetInfo::instance(); - PlannersRegister::registPlanners(); + PlannersRegister::registerPlanners(); std::vector rulesets{&opt::RuleSet::DefaultRules()}; if (FLAGS_enable_optimizer) { diff --git a/src/graph/service/RequestContext.h b/src/graph/service/RequestContext.h index 2486fd72453..a6ccc688543 100644 --- a/src/graph/service/RequestContext.h +++ b/src/graph/service/RequestContext.h @@ -19,7 +19,7 @@ * 1. Create a RequestContext, with statement, session, etc. * 2. Obtain a Future from the context, which is to be returned back to the * Thrift framework. - * 3. Prepare the Response when the request is complished. + * 3. Prepare the Response when the request is completed. * 4. Call `finish' to send the response to the client. */ diff --git a/src/graph/util/ExpressionUtils.cpp b/src/graph/util/ExpressionUtils.cpp index 8b32888bb7a..aff0c9f14ce 100644 --- a/src/graph/util/ExpressionUtils.cpp +++ b/src/graph/util/ExpressionUtils.cpp @@ -354,7 +354,7 @@ Expression *ExpressionUtils::reduceUnaryNotExpr(const Expression *expr) { Expression *ExpressionUtils::rewriteRelExpr(const Expression *expr) { ObjectPool *pool = expr->getObjPool(); - // Match relational expressions containing at least one airthmetic expr + // Match relational expressions containing at least one arithmetic expr auto matcher = [](const Expression *e) -> bool { if (e->isRelExpr()) { auto relExpr = static_cast(e); @@ -421,7 +421,7 @@ Expression *ExpressionUtils::rewriteRelExpr(const Expression *expr) { Expression *ExpressionUtils::rewriteRelExprHelper(const Expression *expr, Expression *&relRightOperandExpr) { ObjectPool *pool = expr->getObjPool(); - // TODO: Support rewrite mul/div expressoion after fixing overflow + // TODO: Support rewrite mul/div expression after fixing overflow auto matcher = [](const Expression *e) -> bool { if (!e->isArithmeticExpr() || e->kind() == Expression::Kind::kMultiply || e->kind() == Expression::Kind::kDivision) @@ -456,7 +456,7 @@ Expression *ExpressionUtils::rewriteRelExprHelper(const Expression *expr, case Expression::Kind::kMinus: relRightOperandExpr = ArithmeticExpression::makeMinus(pool, lexpr, rexpr); break; - // Unsupported arithm kind + // Unsupported arithmetic kind // case Expression::Kind::kMultiply: // case Expression::Kind::kDivision: default: diff --git a/src/graph/util/SchemaUtil.cpp b/src/graph/util/SchemaUtil.cpp index a19e381e4ea..8dbf5eb593b 100644 --- a/src/graph/util/SchemaUtil.cpp +++ b/src/graph/util/SchemaUtil.cpp @@ -322,9 +322,9 @@ bool SchemaUtil::isValidVid(const Value &value) { } StatusOr>> SchemaUtil::getAllVertexProp( - QueryContext *qctx, const SpaceInfo &space, bool withProp) { + QueryContext *qctx, GraphSpaceID spaceId, bool withProp) { // Get all tags in the space - const auto allTagsResult = qctx->schemaMng()->getAllLatestVerTagSchema(space.id); + const auto allTagsResult = qctx->schemaMng()->getAllLatestVerTagSchema(spaceId); NG_RETURN_IF_ERROR(allTagsResult); // allTags: std::unordered_map> diff --git a/src/graph/util/SchemaUtil.h b/src/graph/util/SchemaUtil.h index 3e6f6f13af4..b32e461d130 100644 --- a/src/graph/util/SchemaUtil.h +++ b/src/graph/util/SchemaUtil.h @@ -61,7 +61,7 @@ class SchemaUtil final { // Fetch all tags in the space and retrieve props from tags // only take _tag when withProp is false static StatusOr>> getAllVertexProp(QueryContext* qctx, - const SpaceInfo& space, + GraphSpaceID spaceId, bool withProp); // retrieve prop from specific edgetypes diff --git a/src/graph/validator/AdminJobValidator.h b/src/graph/validator/AdminJobValidator.h index e576db54c20..7d755da88e7 100644 --- a/src/graph/validator/AdminJobValidator.h +++ b/src/graph/validator/AdminJobValidator.h @@ -39,7 +39,7 @@ class AdminJobValidator final : public Validator { case meta::cpp2::AdminCmd::DATA_BALANCE: case meta::cpp2::AdminCmd::LEADER_BALANCE: return true; - // TODO: Also space related, but not available in CreateJobExcutor now. + // TODO: Also space related, but not available in CreateJobExecutor now. case meta::cpp2::AdminCmd::DOWNLOAD: case meta::cpp2::AdminCmd::INGEST: case meta::cpp2::AdminCmd::UNKNOWN: diff --git a/src/graph/validator/FetchVerticesValidator.h b/src/graph/validator/FetchVerticesValidator.h index 476b70c37c8..88f87f6762a 100644 --- a/src/graph/validator/FetchVerticesValidator.h +++ b/src/graph/validator/FetchVerticesValidator.h @@ -21,7 +21,7 @@ class FetchVerticesValidator final : public Validator { private: Status validateImpl() override; - Status validateTag(const NameLabelList* nameLables); + Status validateTag(const NameLabelList* nameLabels); Status validateYield(YieldClause* yield); diff --git a/src/graph/validator/LookupValidator.cpp b/src/graph/validator/LookupValidator.cpp index 640dc4b02a9..d5d18e7eb4a 100644 --- a/src/graph/validator/LookupValidator.cpp +++ b/src/graph/validator/LookupValidator.cpp @@ -469,7 +469,7 @@ StatusOr LookupValidator::checkConstExpr(Expression* expr, // Check prop type if (v.type() != SchemaUtil::propTypeToValueType(type)) { - // allow diffrent types in the IN expression, such as "abc" IN ["abc"] + // allow different types in the IN expression, such as "abc" IN ["abc"] if (!expr->isContainerExpr()) { return Status::SemanticError("Column type error : %s", prop.c_str()); } diff --git a/src/graph/validator/MaintainValidator.cpp b/src/graph/validator/MaintainValidator.cpp index 7c8f9a0dcc7..73483e092ac 100644 --- a/src/graph/validator/MaintainValidator.cpp +++ b/src/graph/validator/MaintainValidator.cpp @@ -37,7 +37,7 @@ static Status validateColumns(const std::vector &columnSp column.set_nullable(property->nullable()); } else if (property->isDefaultValue()) { if (!ExpressionUtils::isEvaluableExpr(property->defaultValue())) { - return Status::SemanticError("Wrong default value experssion `%s'", + return Status::SemanticError("Wrong default value expression `%s'", property->defaultValue()->toString().c_str()); } auto *defaultValueExpr = property->defaultValue(); diff --git a/src/graph/validator/MatchValidator.cpp b/src/graph/validator/MatchValidator.cpp index 8e36383c309..d3ca0b6f1cd 100644 --- a/src/graph/validator/MatchValidator.cpp +++ b/src/graph/validator/MatchValidator.cpp @@ -138,10 +138,10 @@ Status MatchValidator::buildPathExpr(const MatchPath *path, auto *pool = qctx_->objPool(); auto pathBuild = PathBuildExpression::make(pool); for (size_t i = 0; i < edgeInfos.size(); ++i) { - pathBuild->add(VariablePropertyExpression::make(pool, "", nodeInfos[i].alias)); - pathBuild->add(VariablePropertyExpression::make(pool, "", edgeInfos[i].alias)); + pathBuild->add(InputPropertyExpression::make(pool, nodeInfos[i].alias)); + pathBuild->add(InputPropertyExpression::make(pool, edgeInfos[i].alias)); } - pathBuild->add(VariablePropertyExpression::make(pool, "", nodeInfos.back().alias)); + pathBuild->add(InputPropertyExpression::make(pool, nodeInfos.back().alias)); matchClauseCtx.pathBuild = std::move(pathBuild); return Status::OK(); } @@ -182,13 +182,13 @@ Status MatchValidator::buildNodeInfo(const MatchPath *path, } Expression *filter = nullptr; if (props != nullptr) { - auto result = makeSubFilter(alias, props); + auto result = makeNodeSubFilter(props, "*"); NG_RETURN_IF_ERROR(result); filter = result.value(); } else if (node->labels() != nullptr && !node->labels()->labels().empty()) { const auto &labels = node->labels()->labels(); for (const auto &label : labels) { - auto result = makeSubFilter(alias, label->props(), *label->label()); + auto result = makeNodeSubFilter(label->props(), *label->label()); NG_RETURN_IF_ERROR(result); filter = andConnect(pool, filter, result.value()); } @@ -250,7 +250,7 @@ Status MatchValidator::buildEdgeInfo(const MatchPath *path, } Expression *filter = nullptr; if (props != nullptr) { - auto result = makeSubFilter(alias, props); + auto result = makeEdgeSubFilter(props); NG_RETURN_IF_ERROR(result); filter = result.value(); } @@ -424,14 +424,9 @@ Status MatchValidator::validateStepRange(const MatchStepRange *range) const { return Status::SemanticError( "Max hop must be greater equal than min hop: %ld vs. %ld", max, min); } - if (max == std::numeric_limits::max()) { + if (max == std::numeric_limits::max()) { return Status::SemanticError("Cannot set maximum hop for variable length relationships"); } - if (min < 0) { - return Status::SemanticError( - "Cannot set negative steps minumum hop for variable length " - "relationships"); - } return Status::OK(); } @@ -526,16 +521,40 @@ Status MatchValidator::validateUnwind(const UnwindClause *unwindClause, return Status::OK(); } -StatusOr MatchValidator::makeSubFilter(const std::string &alias, - const MapExpression *map, - const std::string &label) const { +StatusOr MatchValidator::makeEdgeSubFilter(const MapExpression *map) const { + auto *pool = qctx_->objPool(); + DCHECK(map != nullptr); + auto &items = map->items(); + DCHECK(!items.empty()); + + if (!ExpressionUtils::isEvaluableExpr(items[0].second)) { + return Status::SemanticError("Props must be constant: `%s'", + items[0].second->toString().c_str()); + } + Expression *root = RelationalExpression::makeEQ( + pool, EdgePropertyExpression::make(pool, "*", items[0].first), items[0].second->clone()); + for (auto i = 1u; i < items.size(); i++) { + if (!ExpressionUtils::isEvaluableExpr(items[i].second)) { + return Status::SemanticError("Props must be constant: `%s'", + items[i].second->toString().c_str()); + } + auto *left = root; + auto *right = RelationalExpression::makeEQ( + pool, EdgePropertyExpression::make(pool, "*", items[i].first), items[i].second->clone()); + root = LogicalExpression::makeAnd(pool, left, right); + } + return root; +} + +StatusOr MatchValidator::makeNodeSubFilter(const MapExpression *map, + const std::string &label) const { auto *pool = qctx_->objPool(); // Node has tag without property if (!label.empty() && map == nullptr) { auto *left = ConstantExpression::make(pool, label); auto *args = ArgumentList::make(pool); - args->addArgument(LabelExpression::make(pool, alias)); + args->addArgument(VertexExpression::make(pool)); auto *right = FunctionCallExpression::make(pool, "tags", args); Expression *root = RelationalExpression::makeIn(pool, left, right); @@ -546,28 +565,20 @@ StatusOr MatchValidator::makeSubFilter(const std::string &alias, auto &items = map->items(); DCHECK(!items.empty()); - // TODO(dutor) Check if evaluable and evaluate - if (items[0].second->kind() != Expression::Kind::kConstant) { + if (!ExpressionUtils::isEvaluableExpr(items[0].second)) { return Status::SemanticError("Props must be constant: `%s'", items[0].second->toString().c_str()); } Expression *root = RelationalExpression::makeEQ( - pool, - LabelAttributeExpression::make( - pool, LabelExpression::make(pool, alias), ConstantExpression::make(pool, items[0].first)), - items[0].second->clone()); + pool, TagPropertyExpression::make(pool, label, items[0].first), items[0].second->clone()); for (auto i = 1u; i < items.size(); i++) { - if (items[i].second->kind() != Expression::Kind::kConstant) { + if (!ExpressionUtils::isEvaluableExpr(items[i].second)) { return Status::SemanticError("Props must be constant: `%s'", items[i].second->toString().c_str()); } auto *left = root; auto *right = RelationalExpression::makeEQ( - pool, - LabelAttributeExpression::make(pool, - LabelExpression::make(pool, alias), - ConstantExpression::make(pool, items[i].first)), - items[i].second->clone()); + pool, TagPropertyExpression::make(pool, label, items[i].first), items[i].second->clone()); root = LogicalExpression::makeAnd(pool, left, right); } return root; @@ -707,8 +718,8 @@ Status MatchValidator::validateGroup(YieldClauseContext &yieldCtx) const { yieldCtx.aggOutputColumnNames_.emplace_back(agg->toString()); } if (!aggs.empty()) { - auto *rewritedExpr = ExpressionUtils::rewriteAgg2VarProp(colExpr); - yieldCtx.projCols_->addColumn(new YieldColumn(rewritedExpr, colOldName)); + auto *rewrittenExpr = ExpressionUtils::rewriteAgg2VarProp(colExpr); + yieldCtx.projCols_->addColumn(new YieldColumn(rewrittenExpr, colOldName)); yieldCtx.projOutputColumnNames_.emplace_back(colOldName); continue; } diff --git a/src/graph/validator/MatchValidator.h b/src/graph/validator/MatchValidator.h index 10e69a1450d..14259adc8d5 100644 --- a/src/graph/validator/MatchValidator.h +++ b/src/graph/validator/MatchValidator.h @@ -59,10 +59,6 @@ class MatchValidator final : public Validator { Status includeExisting(const CypherClauseContextBase *cypherClauseCtx, YieldColumns *columns) const; - StatusOr makeSubFilter(const std::string &alias, - const MapExpression *map, - const std::string &label = "") const; - static Expression *andConnect(ObjectPool *pool, Expression *left, Expression *right); template @@ -93,6 +89,11 @@ class MatchValidator final : public Validator { Status buildOutputs(const YieldColumns *yields); + StatusOr makeEdgeSubFilter(const MapExpression *map) const; + + StatusOr makeNodeSubFilter(const MapExpression *map, + const std::string &label) const; + private: std::unique_ptr matchCtx_; }; diff --git a/src/graph/validator/Validator.h b/src/graph/validator/Validator.h index e2c3fa0ce4d..0568d0eb054 100644 --- a/src/graph/validator/Validator.h +++ b/src/graph/validator/Validator.h @@ -73,7 +73,7 @@ class Validator { void setNoSpaceRequired() { noSpaceRequired_ = true; } - // Whether require choosen space + // Whether require chosen space bool noSpaceRequired() const { return noSpaceRequired_; } const Sentence* sentence() const { return sentence_; } diff --git a/src/graph/validator/test/FetchEdgesTest.cpp b/src/graph/validator/test/FetchEdgesTest.cpp index 8ac2794ae21..5651c0b391c 100644 --- a/src/graph/validator/test/FetchEdgesTest.cpp +++ b/src/graph/validator/test/FetchEdgesTest.cpp @@ -286,10 +286,10 @@ TEST_F(FetchEdgesValidatorTest, FetchEdgesPropFailed) { ASSERT_FALSE(validate("FETCH PROP ON edge1 \"1\"->\"2\" YIELD $$.player.name")); ASSERT_FALSE(validate("FETCH PROP ON edge1 \"1\"->\"2\" YIELD $^.player.name")); - // notexist edge + // nonexistent edge ASSERT_FALSE(validate("FETCH PROP ON not_exist_edge \"1\"->\"2\" YIELD not_exist_edge.prop1")); - // notexist edge property + // nonexistent edge property ASSERT_FALSE(validate("FETCH PROP ON like \"1\"->\"2\" YIELD like.not_exist_prop")); // invalid yield expression diff --git a/src/graph/validator/test/FetchVerticesTest.cpp b/src/graph/validator/test/FetchVerticesTest.cpp index bfa886b81cf..52bcf7eef41 100644 --- a/src/graph/validator/test/FetchVerticesTest.cpp +++ b/src/graph/validator/test/FetchVerticesTest.cpp @@ -673,7 +673,7 @@ TEST_F(FetchVerticesValidatorTest, FetchVerticesPropFailed) { } TEST_F(FetchVerticesValidatorTest, FetchVerticesInputFailed) { - // mismatched varirable + // mismatched variable ASSERT_FALSE( validate("$a = FETCH PROP ON person \"1\" YIELD person.name AS name;" "FETCH PROP ON person $b.name YIELD vertex as node")); @@ -681,7 +681,7 @@ TEST_F(FetchVerticesValidatorTest, FetchVerticesInputFailed) { validate("$a = FETCH PROP ON * \"1\" YIELD person.name AS name;" "FETCH PROP * person $b.name YIELD vertex as node")); - // mismatched varirable property + // mismatched variable property ASSERT_FALSE( validate("$a = FETCH PROP ON person \"1\" YIELD person.name AS name;" "FETCH PROP ON person $a.not_exist_property YIELD vertex as node")); diff --git a/src/graph/validator/test/MatchValidatorTest.cpp b/src/graph/validator/test/MatchValidatorTest.cpp index 4e234d7fd9e..481b09fc7fc 100644 --- a/src/graph/validator/test/MatchValidatorTest.cpp +++ b/src/graph/validator/test/MatchValidatorTest.cpp @@ -16,14 +16,8 @@ TEST_F(MatchValidatorTest, SeekByTagIndex) { { std::string query = "MATCH (v:person) RETURN id(v) AS id;"; std::vector expected = {PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kProject, - // TODO this tag filter could remove in this case - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -32,14 +26,8 @@ TEST_F(MatchValidatorTest, SeekByTagIndex) { { std::string query = "MATCH (v:book) RETURN id(v) AS id;"; std::vector expected = {PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kProject, - // TODO this tag filter could remove in this case - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -48,20 +36,9 @@ TEST_F(MatchValidatorTest, SeekByTagIndex) { { std::string query = "MATCH (p:person)-[:like]->(b:book) RETURN b.name AS book;"; std::vector expected = {PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -78,18 +55,10 @@ TEST_F(MatchValidatorTest, SeekByEdgeIndex) { { std::string query = "MATCH (v1)-[:like]->(v2) RETURN id(v1), id(v2);"; std::vector expected = {PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kProject, - PlanNode::Kind::kGetVertices, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -108,13 +77,8 @@ TEST_F(MatchValidatorTest, groupby) { "avg(distinct n.age) AS age," "labels(n) AS lb;"; std::vector expected = {PlanNode::Kind::kAggregate, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -131,13 +95,8 @@ TEST_F(MatchValidatorTest, groupby) { "labels(n) AS lb;"; std::vector expected = {PlanNode::Kind::kProject, PlanNode::Kind::kAggregate, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -157,13 +116,8 @@ TEST_F(MatchValidatorTest, groupby) { PlanNode::Kind::kSort, PlanNode::Kind::kProject, PlanNode::Kind::kAggregate, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -185,13 +139,8 @@ TEST_F(MatchValidatorTest, groupby) { PlanNode::Kind::kSort, PlanNode::Kind::kProject, PlanNode::Kind::kAggregate, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -207,19 +156,9 @@ TEST_F(MatchValidatorTest, groupby) { "avg(distinct n.age) AS age," "labels(m) AS lb;"; std::vector expected = {PlanNode::Kind::kAggregate, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kProject, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -236,19 +175,9 @@ TEST_F(MatchValidatorTest, groupby) { "labels(m) AS lb;"; std::vector expected = {PlanNode::Kind::kProject, PlanNode::Kind::kAggregate, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kProject, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -266,19 +195,9 @@ TEST_F(MatchValidatorTest, groupby) { "labels(m) AS lb "; std::vector expected = {PlanNode::Kind::kAggregate, PlanNode::Kind::kFilter, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kProject, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -299,19 +218,9 @@ TEST_F(MatchValidatorTest, groupby) { PlanNode::Kind::kLimit, PlanNode::Kind::kAggregate, PlanNode::Kind::kFilter, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kProject, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -331,19 +240,9 @@ TEST_F(MatchValidatorTest, groupby) { PlanNode::Kind::kDedup, PlanNode::Kind::kAggregate, PlanNode::Kind::kFilter, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kProject, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); @@ -360,14 +259,16 @@ TEST_F(MatchValidatorTest, groupby) { "avg(distinct n.age)+1 AS age," "labels(m) AS lb " "SKIP 10 LIMIT 20;"; - std::vector expected = { - PlanNode::Kind::kDataCollect, PlanNode::Kind::kLimit, PlanNode::Kind::kProject, - PlanNode::Kind::kAggregate, PlanNode::Kind::kFilter, PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, PlanNode::Kind::kInnerJoin, PlanNode::Kind::kProject, - PlanNode::Kind::kGetVertices, PlanNode::Kind::kDedup, PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, PlanNode::Kind::kProject, PlanNode::Kind::kFilter, - PlanNode::Kind::kGetNeighbors, PlanNode::Kind::kDedup, PlanNode::Kind::kProject, - PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; + std::vector expected = {PlanNode::Kind::kDataCollect, + PlanNode::Kind::kLimit, + PlanNode::Kind::kProject, + PlanNode::Kind::kAggregate, + PlanNode::Kind::kFilter, + PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, + PlanNode::Kind::kIndexScan, + PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); } { @@ -383,15 +284,18 @@ TEST_F(MatchValidatorTest, groupby) { "labels(m) AS lb " "ORDER BY id " "SKIP 10 LIMIT 20;"; - std::vector expected = { - PlanNode::Kind::kDataCollect, PlanNode::Kind::kLimit, PlanNode::Kind::kSort, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, PlanNode::Kind::kAggregate, - PlanNode::Kind::kFilter, PlanNode::Kind::kFilter, PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, PlanNode::Kind::kProject, PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, PlanNode::Kind::kFilter, PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, PlanNode::Kind::kIndexScan, - PlanNode::Kind::kStart}; + std::vector expected = {PlanNode::Kind::kDataCollect, + PlanNode::Kind::kLimit, + PlanNode::Kind::kSort, + PlanNode::Kind::kDedup, + PlanNode::Kind::kProject, + PlanNode::Kind::kAggregate, + PlanNode::Kind::kFilter, + PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, + PlanNode::Kind::kIndexScan, + PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); } { @@ -407,14 +311,17 @@ TEST_F(MatchValidatorTest, groupby) { "labels(m) AS lb " "ORDER BY id " "SKIP 10 LIMIT 20;"; - std::vector expected = { - PlanNode::Kind::kDataCollect, PlanNode::Kind::kLimit, PlanNode::Kind::kSort, - PlanNode::Kind::kDedup, PlanNode::Kind::kAggregate, PlanNode::Kind::kFilter, - PlanNode::Kind::kFilter, PlanNode::Kind::kProject, PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kProject, PlanNode::Kind::kGetVertices, PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, PlanNode::Kind::kFilter, PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, PlanNode::Kind::kGetNeighbors, PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; + std::vector expected = {PlanNode::Kind::kDataCollect, + PlanNode::Kind::kLimit, + PlanNode::Kind::kSort, + PlanNode::Kind::kDedup, + PlanNode::Kind::kAggregate, + PlanNode::Kind::kFilter, + PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, + PlanNode::Kind::kIndexScan, + PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); } { @@ -430,17 +337,19 @@ TEST_F(MatchValidatorTest, groupby) { "labels(m) AS lb " "ORDER BY id " "SKIP 10 LIMIT 20;"; - std::vector expected = { - PlanNode::Kind::kDataCollect, PlanNode::Kind::kLimit, PlanNode::Kind::kSort, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, PlanNode::Kind::kAggregate, - PlanNode::Kind::kFilter, PlanNode::Kind::kFilter, PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, PlanNode::Kind::kProject, PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kFilter, PlanNode::Kind::kProject, PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, PlanNode::Kind::kFilter, PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, PlanNode::Kind::kIndexScan, - PlanNode::Kind::kStart}; + std::vector expected = {PlanNode::Kind::kDataCollect, + PlanNode::Kind::kLimit, + PlanNode::Kind::kSort, + PlanNode::Kind::kDedup, + PlanNode::Kind::kProject, + PlanNode::Kind::kAggregate, + PlanNode::Kind::kFilter, + PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, + PlanNode::Kind::kTraverse, + PlanNode::Kind::kIndexScan, + PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); } } @@ -454,19 +363,9 @@ TEST_F(MatchValidatorTest, with) { std::vector expected = {PlanNode::Kind::kProject, PlanNode::Kind::kProject, PlanNode::Kind::kAggregate, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kInnerJoin, - PlanNode::Kind::kProject, - PlanNode::Kind::kGetVertices, - PlanNode::Kind::kDedup, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kProject, - PlanNode::Kind::kFilter, - PlanNode::Kind::kGetNeighbors, - PlanNode::Kind::kDedup, PlanNode::Kind::kProject, + PlanNode::Kind::kAppendVertices, + PlanNode::Kind::kTraverse, PlanNode::Kind::kIndexScan, PlanNode::Kind::kStart}; EXPECT_TRUE(checkResult(query, expected)); diff --git a/src/graph/validator/test/MockSchemaManager.h b/src/graph/validator/test/MockSchemaManager.h index 46b14c1eb6a..e13ef680d21 100644 --- a/src/graph/validator/test/MockSchemaManager.h +++ b/src/graph/validator/test/MockSchemaManager.h @@ -76,7 +76,7 @@ class MockSchemaManager final : public nebula::meta::SchemaManager { return allVerTagSchemas; } - // Returns all latest version of schesmas of all tags in the given space + // Returns all latest version of schemas of all tags in the given space StatusOr getAllLatestVerTagSchema(GraphSpaceID space) override { meta::TagSchema allLatestVerTagSchemas; const auto& tagSchemas = tagSchemas_[space]; diff --git a/src/graph/validator/test/MutateValidatorTest.cpp b/src/graph/validator/test/MutateValidatorTest.cpp index cb8fd8a371a..add40824ae8 100644 --- a/src/graph/validator/test/MutateValidatorTest.cpp +++ b/src/graph/validator/test/MutateValidatorTest.cpp @@ -201,13 +201,13 @@ TEST_F(MutateValidatorTest, UpdateEdgeTest) { auto cmd = "UPDATE EDGE ON study \"Tom\"->\"Lily\" SET count = 1"; ASSERT_FALSE(checkResult(cmd, {})); } - // Wrong expr "$^.peson.age" + // Wrong expr "$^.person_.age" { auto cmd = "UPDATE EDGE \"Tom\"->\"Lily\" OF like " "SET end = like.end + 1 " - "WHEN $^.peson.age >= 18 " - "YIELD $^.peson.age AS age, like.end AS end"; + "WHEN $^.person_.age >= 18 " + "YIELD $^.person_.age AS age, like.end AS end"; ASSERT_FALSE(checkResult(cmd, {})); } // 1.0 syntax succeed diff --git a/src/graph/validator/test/QueryValidatorTest.cpp b/src/graph/validator/test/QueryValidatorTest.cpp index f50c22c27c6..6af43b84454 100644 --- a/src/graph/validator/test/QueryValidatorTest.cpp +++ b/src/graph/validator/test/QueryValidatorTest.cpp @@ -1015,7 +1015,7 @@ TEST_F(QueryValidatorTest, OrderBy) { } } -TEST_F(QueryValidatorTest, OrderByAndLimt) { +TEST_F(QueryValidatorTest, OrderByAndLimit) { { std::string query = "GO FROM \"Ann\" OVER like YIELD $^.person.age AS age" @@ -1177,19 +1177,9 @@ TEST_F(QueryValidatorTest, TestMatch) { "RETURN type(r) AS Type, v2.name AS Name"; std::vector expected = { PK::kProject, - PK::kFilter, - PK::kProject, - PK::kInnerJoin, - PK::kProject, - PK::kGetVertices, - PK::kDedup, - PK::kProject, - PK::kFilter, - PK::kProject, - PK::kFilter, - PK::kGetNeighbors, - PK::kDedup, PK::kProject, + PK::kAppendVertices, + PK::kTraverse, PK::kIndexScan, PK::kStart, }; @@ -1200,11 +1190,15 @@ TEST_F(QueryValidatorTest, TestMatch) { "MATCH (:person{name:'Dwyane Wade'}) -[:like]-> () -[:like]-> (v3) " "RETURN DISTINCT v3.name AS Name"; std::vector expected = { - PK::kDataCollect, PK::kDedup, PK::kProject, PK::kFilter, PK::kProject, - PK::kInnerJoin, PK::kProject, PK::kGetVertices, PK::kDedup, PK::kProject, - PK::kInnerJoin, PK::kFilter, PK::kProject, PK::kGetNeighbors, PK::kDedup, - PK::kProject, PK::kFilter, PK::kProject, PK::kFilter, PK::kGetNeighbors, - PK::kDedup, PK::kProject, PK::kIndexScan, PK::kStart, + PK::kDataCollect, + PK::kDedup, + PK::kProject, + PK::kProject, + PK::kAppendVertices, + PK::kTraverse, + PK::kTraverse, + PK::kIndexScan, + PK::kStart, }; EXPECT_TRUE(checkResult(query, expected)); } @@ -1216,18 +1210,10 @@ TEST_F(QueryValidatorTest, TestMatch) { std::vector expected = { PK::kProject, PK::kFilter, - PK::kFilter, PK::kProject, - PK::kInnerJoin, - PK::kProject, - PK::kGetVertices, + PK::kAppendVertices, + PK::kTraverse, PK::kDedup, - PK::kProject, - PK::kFilter, - PK::kProject, - PK::kGetNeighbors, - PK::kDedup, - PK::kProject, PK::kPassThrough, PK::kStart, }; @@ -1238,53 +1224,25 @@ TEST_F(QueryValidatorTest, TestMatch) { "MATCH (v1)-[e:serve*2..3{start_year: 2000}]-(v2) " "WHERE id(v1) == \"LeBron James\"" "RETURN v1, v2"; - std::vector expected = {PK::kProject, - PK::kFilter, - PK::kFilter, - PK::kProject, - PK::kInnerJoin, - PK::kProject, - PK::kGetVertices, - PK::kDedup, - PK::kProject, - PK::kFilter, - PK::kUnionAllVersionVar, - PK::kLoop, - PK::kProject, - PK::kFilter, - PK::kFilter, - PK::kProject, - PK::kGetNeighbors, - PK::kInnerJoin, - PK::kDedup, - PK::kProject, - PK::kProject, - PK::kFilter, - PK::kPassThrough, - PK::kGetNeighbors, - PK::kStart, - PK::kDedup, - PK::kProject, - PK::kStart}; - EXPECT_TRUE(checkResult(query, expected)); - } - { - std::string query = "MATCH p = (n)-[]-(m:person{name:\"LeBron James\"}) RETURN p"; std::vector expected = { PK::kProject, PK::kFilter, PK::kProject, - PK::kInnerJoin, - PK::kProject, - PK::kGetVertices, + PK::kAppendVertices, + PK::kTraverse, PK::kDedup, + PK::kPassThrough, + PK::kStart, + }; + EXPECT_TRUE(checkResult(query, expected)); + } + { + std::string query = "MATCH p = (n)-[]-(m:person{name:\"LeBron James\"}) RETURN p"; + std::vector expected = { PK::kProject, - PK::kFilter, - PK::kProject, - PK::kFilter, - PK::kGetNeighbors, - PK::kDedup, PK::kProject, + PK::kAppendVertices, + PK::kTraverse, PK::kIndexScan, PK::kStart, }; diff --git a/src/graph/validator/test/ValidatorTestBase.cpp b/src/graph/validator/test/ValidatorTestBase.cpp index 6ed2caa50ba..a76c3f89227 100644 --- a/src/graph/validator/test/ValidatorTestBase.cpp +++ b/src/graph/validator/test/ValidatorTestBase.cpp @@ -195,7 +195,7 @@ Status ValidatorTestBase::EqSelf(const PlanNode *l, const PlanNode *r) { // V // E // this will traversal sub-tree [D->E] twice but not matter the Equal result -// TODO(shylock) maybe need check the toplogy of `Select` and `Loop` +// TODO(shylock) maybe need check the topology of `Select` and `Loop` /*static*/ Status ValidatorTestBase::Eq(const PlanNode *l, const PlanNode *r) { auto result = EqSelf(l, r); if (!result.ok()) { diff --git a/src/graph/validator/test/ValidatorTestBase.h b/src/graph/validator/test/ValidatorTestBase.h index 14c7abe5a8a..38ccf3fbb75 100644 --- a/src/graph/validator/test/ValidatorTestBase.h +++ b/src/graph/validator/test/ValidatorTestBase.h @@ -41,7 +41,7 @@ class ValidatorTestBase : public ::testing::Test { schemaMng_ = CHECK_NOTNULL(MockSchemaManager::makeUnique()); indexMng_ = CHECK_NOTNULL(MockIndexManager::makeUnique()); pool_ = std::make_unique(); - PlannersRegister::registPlanners(); + PlannersRegister::registerPlanners(); } StatusOr validate(const std::string& query) { diff --git a/src/graph/validator/test/YieldValidatorTest.cpp b/src/graph/validator/test/YieldValidatorTest.cpp index ed1ec6070e8..1dec793100b 100644 --- a/src/graph/validator/test/YieldValidatorTest.cpp +++ b/src/graph/validator/test/YieldValidatorTest.cpp @@ -92,7 +92,7 @@ TEST_F(YieldValidatorTest, Logic) { #endif } -TEST_F(YieldValidatorTest, FuncitonCall) { +TEST_F(YieldValidatorTest, FunctionCall) { #if 0 { // TODO not support udf_is_in diff --git a/src/graph/visitor/ExtractPropExprVisitor.h b/src/graph/visitor/ExtractPropExprVisitor.h index 483c68640b5..5eda485de80 100644 --- a/src/graph/visitor/ExtractPropExprVisitor.h +++ b/src/graph/visitor/ExtractPropExprVisitor.h @@ -2,8 +2,8 @@ * * This source code is licensed under Apache 2.0 License. */ -#ifndef GRAPH_VISITOR_EXTRACTPROPEXPRVISITON_H_ -#define GRAPH_VISITOR_EXTRACTPROPEXPRVISITON_H_ +#ifndef GRAPH_VISITOR_EXTRACTPROPEXPRVISITOR_H_ +#define GRAPH_VISITOR_EXTRACTPROPEXPRVISITOR_H_ #include "graph/context/ValidateContext.h" #include "graph/visitor/ExprVisitorImpl.h" @@ -74,4 +74,4 @@ class ExtractPropExprVisitor final : public ExprVisitorImpl { } // namespace graph } // namespace nebula -#endif // GRAPH_VISITOR_EXTRACTPROPEXPRVISITON_H_ +#endif // GRAPH_VISITOR_EXTRACTPROPEXPRVISITOR_H_ diff --git a/src/graph/visitor/FoldConstantExprVisitor.cpp b/src/graph/visitor/FoldConstantExprVisitor.cpp index e8cf157fe14..dd970696774 100644 --- a/src/graph/visitor/FoldConstantExprVisitor.cpp +++ b/src/graph/visitor/FoldConstantExprVisitor.cpp @@ -337,7 +337,7 @@ void FoldConstantExprVisitor::visitBinaryExpr(BinaryExpression *expr) { } Expression *FoldConstantExprVisitor::fold(Expression *expr) { - // Container expresison should remain the same type after being folded + // Container expression should remain the same type after being folded if (expr->isContainerExpr()) { return expr; } diff --git a/src/graph/visitor/FoldConstantExprVisitor.h b/src/graph/visitor/FoldConstantExprVisitor.h index 9a913a31ca4..0aa77b798d4 100644 --- a/src/graph/visitor/FoldConstantExprVisitor.h +++ b/src/graph/visitor/FoldConstantExprVisitor.h @@ -79,7 +79,7 @@ class FoldConstantExprVisitor final : public ExprVisitor { Expression *fold(Expression *expr); private: - // Obejct pool used to manage expressions generated during visiting + // Object pool used to manage expressions generated during visiting ObjectPool *pool_; bool canBeFolded_{false}; Status status_; diff --git a/src/graph/visitor/test/RewriteRelExprVisitorTest.cpp b/src/graph/visitor/test/RewriteRelExprVisitorTest.cpp index 13cffb278a4..1ca02836784 100644 --- a/src/graph/visitor/test/RewriteRelExprVisitorTest.cpp +++ b/src/graph/visitor/test/RewriteRelExprVisitorTest.cpp @@ -35,7 +35,7 @@ TEST_F(RewriteRelExprVisitorTest, TestArithmeticalExpr) { auto expected = ltExpr(laExpr("v", "age"), minusExpr(constantExpr(40), constantExpr(-1))); ASSERT_EQ(*res, *expected) << res->toString() << " vs. " << expected->toString(); } - // (label1 + label2 < 40) => (label1 + label2 < 40) Unchaged + // (label1 + label2 < 40) => (label1 + label2 < 40) Unchanged // TODO: replace list with set in object pool and avoid copy { auto expr = ltExpr(addExpr(laExpr("v", "age"), laExpr("v2", "age2")), constantExpr(40)); diff --git a/src/graph/visitor/test/RewriteUnaryNotExprVisitorTest.cpp b/src/graph/visitor/test/RewriteUnaryNotExprVisitorTest.cpp index c05a6744454..9704a5b6cfc 100644 --- a/src/graph/visitor/test/RewriteUnaryNotExprVisitorTest.cpp +++ b/src/graph/visitor/test/RewriteUnaryNotExprVisitorTest.cpp @@ -105,7 +105,7 @@ TEST_F(RewriteUnaryNotExprVisitorTest, TestMultipleUnaryNotContainerExpr) { TEST_F(RewriteUnaryNotExprVisitorTest, TestRelExpr) { // (5 == 10) => (5 == 10) - // no change should be made to the orginal expression + // no change should be made to the original expression { auto original = eqExpr(constantExpr(5), constantExpr(10)); auto res = ExpressionUtils::reduceUnaryNotExpr(original); diff --git a/src/graph/visitor/test/VisitorTestBase.h b/src/graph/visitor/test/VisitorTestBase.h index 76991d8a11d..003bf7ccd61 100644 --- a/src/graph/visitor/test/VisitorTestBase.h +++ b/src/graph/visitor/test/VisitorTestBase.h @@ -153,14 +153,14 @@ class VisitorTestBase : public ::testing::Test { } CaseExpression *caseExpr(Expression *cond, - Expression *defaltResult, + Expression *defaultResult, Expression *when, Expression *then) { auto caseList = CaseList::make(pool); caseList->add(when, then); auto expr = CaseExpression::make(pool, caseList); expr->setCondition(cond); - expr->setDefault(defaltResult); + expr->setDefault(defaultResult); return expr; } diff --git a/src/interface/common.thrift b/src/interface/common.thrift index 463fceb2c24..abcc25faeca 100644 --- a/src/interface/common.thrift +++ b/src/interface/common.thrift @@ -35,6 +35,7 @@ cpp_include "common/datatypes/GeographyOps-inl.h" const binary (cpp.type = "char const *") version = "2.6.0" +typedef i64 (cpp.type = "nebula::ClusterID") ClusterID typedef i32 (cpp.type = "nebula::GraphSpaceID") GraphSpaceID typedef i32 (cpp.type = "nebula::PartitionID") PartitionID typedef i32 (cpp.type = "nebula::TagID") TagID @@ -251,6 +252,11 @@ struct CheckpointInfo { 2: binary path, } +// used for raft and drainer +struct LogEntry { + 1: ClusterID cluster; + 2: binary log_str; +} // These are all data types supported in the graph properties enum PropertyType { @@ -263,7 +269,7 @@ enum PropertyType { FLOAT = 4, DOUBLE = 5, STRING = 6, - // String with fixed length. If the string content is shorteri + // String with fixed length. If the string content is shorter // than the given length, '\0' will be padded to the end FIXED_STRING = 7, // New in v2 INT8 = 8, // New in v2 @@ -355,7 +361,7 @@ enum ErrorCode { E_BALANCED = -2024, E_NO_RUNNING_BALANCE_PLAN = -2025, E_NO_VALID_HOST = -2026, - E_CORRUPTTED_BALANCE_PLAN = -2027, + E_CORRUPTED_BALANCE_PLAN = -2027, E_NO_INVALID_BALANCE_PLAN = -2028, diff --git a/src/interface/raftex.thrift b/src/interface/raftex.thrift index 20972b82af7..8f1a8ea4f47 100644 --- a/src/interface/raftex.thrift +++ b/src/interface/raftex.thrift @@ -5,34 +5,32 @@ namespace cpp nebula.raftex -cpp_include "common/thrift/ThriftTypes.h" +include "common.thrift" enum ErrorCode { SUCCEEDED = 0; - E_LOG_GAP = -1; - E_LOG_STALE = -2; - E_MISSING_COMMIT = -3; - E_WAITING_SNAPSHOT = -4; // The follower is waiting a snapshot + E_UNKNOWN_PART = -1; - E_UNKNOWN_PART = -5; - E_TERM_OUT_OF_DATE = -6; - E_LAST_LOG_TERM_TOO_OLD = -7; - E_BAD_STATE = -8; - E_WRONG_LEADER = -9; - E_WAL_FAIL = -10; - E_NOT_READY = -11; - - // Local errors - E_HOST_STOPPED = -12; - E_NOT_A_LEADER = -13; - E_HOST_DISCONNECTED = -14; - E_TOO_MANY_REQUESTS = -15; - E_PERSIST_SNAPSHOT_FAILED = -16; + // Raft consensus errors + E_LOG_GAP = -2; + E_LOG_STALE = -3; + E_TERM_OUT_OF_DATE = -4; - E_BAD_ROLE = -17, + // Raft state errors + E_WAITING_SNAPSHOT = -5; // The follower is waiting a snapshot + E_BAD_STATE = -6; + E_WRONG_LEADER = -7; + E_NOT_READY = -8; + E_BAD_ROLE = -9, - E_EXCEPTION = -20; // An thrift internal exception was thrown + // Local errors + E_WAL_FAIL = -10; + E_HOST_STOPPED = -11; + E_TOO_MANY_REQUESTS = -12; + E_PERSIST_SNAPSHOT_FAILED = -13; + E_RPC_EXCEPTION = -14; // An thrift internal exception was thrown + E_NO_WAL_FOUND = -15; } typedef i64 (cpp.type = "nebula::ClusterID") ClusterID @@ -61,12 +59,6 @@ struct AskForVoteResponse { } -struct LogEntry { - 1: ClusterID cluster; - 2: binary log_str; -} - - /* AppendLogRequest serves two purposes: @@ -102,9 +94,7 @@ struct AppendLogRequest { // which specified by log_term // 10: TermID log_term; - 11: list log_str_list; - - 12: bool sending_snapshot; + 11: list log_str_list; } diff --git a/src/interface/storage.thrift b/src/interface/storage.thrift index e4ff187305c..3451fd8b8e2 100644 --- a/src/interface/storage.thrift +++ b/src/interface/storage.thrift @@ -30,7 +30,7 @@ struct RequestCommon { struct PartitionResult { 1: required common.ErrorCode code, 2: required common.PartitionID part_id, - // Only valid when code is E_LEADER_CHANAGED. + // Only valid when code is E_LEADER_CHANGED. 3: optional common.HostAddr leader, } @@ -63,7 +63,7 @@ enum StatType { struct StatProp { // Alias of the stats property 1: binary alias, - // An eperssion. In most of cases, it is a reference to a specific property + // An expression. In most of cases, it is a reference to a specific property 2: binary prop, // Stats method 3: StatType stat, @@ -74,7 +74,7 @@ struct StatProp { struct Expr { // Alias of the expression 1: binary alias, - // An eperssion. It could be any valid expression, + // An expression. It could be any valid expression, 2: binary expr, } @@ -127,7 +127,7 @@ enum EdgeDirection { struct TraverseSpec { // When edge_type > 0, going along the out-edge, otherwise, along the in-edge - // If the edge type list is empty, all edges will be scaned + // If the edge type list is empty, all edges will be scanned 1: list edge_types, // When above edge_types is not empty, edge_direction should be ignored // When edge_types is empty, edge_direction decided which edge types will be @@ -156,7 +156,7 @@ struct TraverseSpec { 9: optional bool random, // Return the top/bottom N rows for each given vertex 10: optional i64 limit, - // If provided, only the rows satified the given expression will be returned + // If provided, only the rows satisfied the given expression will be returned 11: optional binary filter, } @@ -286,7 +286,7 @@ struct GetPropResponse { // | ..... | // ==================================== // - // Each column represents one peoperty. the column name is in the form of "tag_name.prop_alias" + // Each column represents one property. the column name is in the form of "tag_name.prop_alias" // or "edge_type_name.prop_alias" in the same order which specified in VertexProp or EdgeProp // // If the request is to get tag prop, the first column will **always** be the vid, @@ -341,7 +341,7 @@ struct AddVerticesRequest { // in the NewVertex.NewTag.props 3: map> (cpp.template = "std::unordered_map") prop_names, - // if ture, when (vertexID,tagID) already exists, do nothing + // if true, when (vertexID,tagID) already exists, do nothing 4: bool if_not_exists, 5: optional RequestCommon common, } @@ -354,7 +354,7 @@ struct AddEdgesRequest { // A list of property names. The order of the property names should match // the data order specified in the NewEdge.props 3: list prop_names, - // if ture, when edge already exists, do nothing + // if true, when edge already exists, do nothing 4: bool if_not_exists, 5: optional RequestCommon common, } @@ -407,7 +407,7 @@ struct UpdateResponse { // The name of the first column is "_inserted". It has a boolean value. It's // TRUE if insertion happens // Starting from the second column, it's the all returned properties, one column - // per peoperty. If there is no given property, the value will be a NULL + // per property. If there is no given property, the value will be a NULL 2: optional common.DataSet props, } @@ -489,7 +489,7 @@ struct LookupIndexResp { // properties; when looking up the edge index, each row represents one edge // and its properties. // - // Each column represents one peoperty. the column name is in the form of "tag_name.prop_alias" + // Each column represents one property. the column name is in the form of "tag_name.prop_alias" // or "edge_type_name.prop_alias" in the same order which specified in return_columns of request 2: optional common.DataSet data, } @@ -618,7 +618,7 @@ struct ScanEdgeResponse { 1: required ResponseCommon result, // The data will return as a dataset. The format is as follows: // Each column represents one property. the column name is in the form of "edge_name.prop_alias" - // in the same order which specified in EdgeProp in requesss. + // in the same order which specified in EdgeProp in requests. 2: common.DataSet edge_data, 3: map (cpp.template = "std::unordered_map") cursors; @@ -627,11 +627,11 @@ struct ScanEdgeResponse { struct TaskPara { 1: common.GraphSpaceID space_id, 2: optional list parts, - 3: optional list task_specfic_paras + 3: optional list task_specific_paras } struct AddAdminTaskRequest { - // rebuild index / flush / compact / statis + // rebuild index / flush / compact / stats 1: meta.AdminCmd cmd 2: i32 job_id 3: i32 task_id @@ -889,7 +889,7 @@ struct ChainAddEdgesRequest { // A list of property names. The order of the property names should match // the data order specified in the NewEdge.props 3: list prop_names, - // if ture, when edge already exists, do nothing + // if true, when edge already exists, do nothing 4: bool if_not_exists, // 5: map term_of_parts, 5: i64 term diff --git a/src/kvstore/DiskManager.h b/src/kvstore/DiskManager.h index 8e00689dc4e..4c0afe3c9a1 100644 --- a/src/kvstore/DiskManager.h +++ b/src/kvstore/DiskManager.h @@ -35,8 +35,8 @@ class DiskManager { // Canonical path which contains the specified space and part, e.g. // "/DataPath/nebula/spaceId". As for one storage instance, at most one path - // should contain a parition. Note that there isn't a separate dir for a - // parititon (except wal), so we return space dir + // should contain a partition. Note that there isn't a separate dir for a + // partition (except wal), so we return space dir StatusOr path(GraphSpaceID spaceId, PartitionID partId); // pre-condition: path is the space path, so it must end with /nebula/spaceId diff --git a/src/kvstore/Listener.cpp b/src/kvstore/Listener.cpp index 7e0dd60bac3..f99ad2476e7 100644 --- a/src/kvstore/Listener.cpp +++ b/src/kvstore/Listener.cpp @@ -191,7 +191,7 @@ void Listener::doApply() { case OP_BATCH_WRITE: { auto batch = decodeBatchValue(log); for (auto& op : batch) { - // OP_BATCH_PUT and OP_BATCH_REMOVE_RANGE is igored + // OP_BATCH_PUT and OP_BATCH_REMOVE_RANGE is ignored if (op.first == BatchLogType::OP_BATCH_PUT) { data.emplace_back(op.second.first, op.second.second); } diff --git a/src/kvstore/NebulaSnapshotManager.cpp b/src/kvstore/NebulaSnapshotManager.cpp index 6a2fd3ec8fc..f9401ca04fb 100644 --- a/src/kvstore/NebulaSnapshotManager.cpp +++ b/src/kvstore/NebulaSnapshotManager.cpp @@ -10,7 +10,7 @@ #include "kvstore/RateLimiter.h" DEFINE_uint32(snapshot_part_rate_limit, - 1024 * 1024 * 8, + 1024 * 1024 * 10, "max bytes of pulling snapshot for each partition in one second"); DEFINE_uint32(snapshot_batch_size, 1024 * 512, "batch size for snapshot, in bytes"); @@ -21,7 +21,7 @@ const int32_t kReserveNum = 1024 * 4; NebulaSnapshotManager::NebulaSnapshotManager(NebulaStore* kv) : store_(kv) { // Snapshot rate is limited to FLAGS_snapshot_worker_threads * FLAGS_snapshot_part_rate_limit. - // So by default, the total send rate is limited to 4 * 8Mb = 32Mb. + // So by default, the total send rate is limited to 4 * 10Mb = 40Mb. LOG(INFO) << "Send snapshot is rate limited to " << FLAGS_snapshot_part_rate_limit << " for each part by default"; } diff --git a/src/kvstore/NebulaStore.cpp b/src/kvstore/NebulaStore.cpp index adcf2d762e5..e9675500ac9 100644 --- a/src/kvstore/NebulaStore.cpp +++ b/src/kvstore/NebulaStore.cpp @@ -22,7 +22,7 @@ DEFINE_int32(custom_filter_interval_secs, "interval to trigger custom compaction, < 0 means always do " "default minor compaction"); DEFINE_int32(num_workers, 4, "Number of worker threads"); -DEFINE_int32(clean_wal_interval_secs, 600, "inerval to trigger clean expired wal"); +DEFINE_int32(clean_wal_interval_secs, 600, "interval to trigger clean expired wal"); DEFINE_bool(auto_remove_invalid_space, false, "whether remove data of invalid space when restart"); DECLARE_bool(rocksdb_disable_wal); @@ -558,7 +558,7 @@ void NebulaStore::removeSpaceDir(const std::string& dir) { LOG(INFO) << "Try to remove space directory: " << dir; boost::filesystem::remove_all(dir); } catch (const boost::filesystem::filesystem_error& e) { - LOG(ERROR) << "Exception caught while remove directory, please delelte it by manual: " + LOG(ERROR) << "Exception caught while remove directory, please delete it by manual: " << e.what(); } } diff --git a/src/kvstore/Part.cpp b/src/kvstore/Part.cpp index feb83df0768..f3f2830fcd4 100644 --- a/src/kvstore/Part.cpp +++ b/src/kvstore/Part.cpp @@ -201,9 +201,9 @@ void Part::onLeaderReady(TermID term) { } } -void Part::registerOnLeaderReady(LeaderChagneCB cb) { leaderReadyCB_.emplace_back(std::move(cb)); } +void Part::registerOnLeaderReady(LeaderChangeCB cb) { leaderReadyCB_.emplace_back(std::move(cb)); } -void Part::registerOnLeaderLost(LeaderChagneCB cb) { leaderLostCB_.emplace_back(std::move(cb)); } +void Part::registerOnLeaderLost(LeaderChangeCB cb) { leaderLostCB_.emplace_back(std::move(cb)); } void Part::onDiscoverNewLeader(HostAddr nLeader) { LOG(INFO) << idStr_ << "Find the new leader " << nLeader; @@ -457,7 +457,7 @@ bool Part::preProcessLog(LogID logId, TermID termId, ClusterID clusterId, const void Part::cleanup() { LOG(INFO) << idStr_ << "Clean rocksdb part data"; // Remove the vertex, edge, index, systemCommitKey, operation data under the part - const auto& vertexPre = NebulaKeyUtils::vertexPrefix(partId_); + const auto& vertexPre = NebulaKeyUtils::tagPrefix(partId_); auto ret = engine_->removeRange(NebulaKeyUtils::firstKey(vertexPre, vIdLen_), NebulaKeyUtils::lastKey(vertexPre, vIdLen_)); if (ret != nebula::cpp2::ErrorCode::SUCCEEDED) { diff --git a/src/kvstore/Part.h b/src/kvstore/Part.h index 0af34aba900..c11a43ba4e7 100644 --- a/src/kvstore/Part.h +++ b/src/kvstore/Part.h @@ -115,18 +115,18 @@ class Part : public raftex::RaftPart { TermID term; }; - using LeaderChagneCB = std::function; - void registerOnLeaderReady(LeaderChagneCB cb); + using LeaderChangeCB = std::function; + void registerOnLeaderReady(LeaderChangeCB cb); - void registerOnLeaderLost(LeaderChagneCB cb); + void registerOnLeaderLost(LeaderChangeCB cb); protected: GraphSpaceID spaceId_; PartitionID partId_; std::string walPath_; NewLeaderCallback newLeaderCb_ = nullptr; - std::vector leaderReadyCB_; - std::vector leaderLostCB_; + std::vector leaderReadyCB_; + std::vector leaderLostCB_; private: KVEngine* engine_ = nullptr; diff --git a/src/kvstore/RateLimiter.h b/src/kvstore/RateLimiter.h index 5f0e341a6ad..727049b4bf9 100644 --- a/src/kvstore/RateLimiter.h +++ b/src/kvstore/RateLimiter.h @@ -16,7 +16,7 @@ DECLARE_bool(skip_wait_in_rate_limiter); namespace nebula { namespace kvstore { -// A simple wrapper for foly::TokenBucket, it would limit the speed to rate_ * buckets_.size(). +// A simple wrapper for folly::TokenBucket, it would limit the speed to rate_ * buckets_.size(). // For now, there are two major cases: snapshot (both for balance or catch up) and rebuild index. class RateLimiter { public: @@ -27,15 +27,15 @@ class RateLimiter { bucket_.reset(new folly::DynamicTokenBucket(static_cast(now + waitInSec))); } - // Caller must make sure the **the parition has been add, and won't be removed during consume.** - // Snaphot and rebuild index follow this principle by design. + // Caller must make sure the **the partition has been add, and won't be removed during consume.** + // Snapshot and rebuild index follow this principle by design. void consume(double toConsume, double rate, double burstSize) { if (toConsume > burstSize) { // consumeWithBorrowAndWait do nothing when toConsume > burstSize_, we sleep 1s instead std::this_thread::sleep_for(std::chrono::seconds(1)); } else { - // If there are enouth tokens, consume and return immediately. - // If not, cosume anyway, but sleep enough time before return. + // If there are enough tokens, consume and return immediately. + // If not, consume anyway, but sleep enough time before return. auto now = time::WallClock::fastNowInSec(); bucket_->consumeWithBorrowAndWait(toConsume, rate, burstSize, static_cast(now)); } diff --git a/src/kvstore/RocksEngine.cpp b/src/kvstore/RocksEngine.cpp index c3af0a8a3fe..e386743c415 100644 --- a/src/kvstore/RocksEngine.cpp +++ b/src/kvstore/RocksEngine.cpp @@ -213,7 +213,7 @@ nebula::cpp2::ErrorCode RocksEngine::range(const std::string& start, nebula::cpp2::ErrorCode RocksEngine::prefix(const std::string& prefix, std::unique_ptr* storageIter) { // In fact, we don't need to check prefix.size() >= extractorLen_, which is caller's duty to make - // sure the prefix bloom filter exists. But this is quite error-proning, so we do a check here. + // sure the prefix bloom filter exists. But this is quite error-prone, so we do a check here. if (FLAGS_enable_rocksdb_prefix_filtering && prefix.size() >= extractorLen_) { return prefixWithExtractor(prefix, storageIter); } else { @@ -517,7 +517,7 @@ void RocksEngine::openBackupEngine(GraphSpaceID spaceId) { } else if (!status.ok()) { LOG(FATAL) << status.ToString(); } - LOG(INFO) << "restore from latest backup succesfully" + LOG(INFO) << "restore from latest backup successfully" << ", backup path " << backupPath_ << ", wal path " << walDir << ", data path " << dataPath; } diff --git a/src/kvstore/RocksEngine.h b/src/kvstore/RocksEngine.h index 5542ab89784..06226b5789c 100644 --- a/src/kvstore/RocksEngine.h +++ b/src/kvstore/RocksEngine.h @@ -120,7 +120,7 @@ class RocksEngine : public KVEngine { void stop() override; - // return path to a spaceId, e.g. "/DataPath/nebula/spaceId", usally it should + // return path to a spaceId, e.g. "/DataPath/nebula/spaceId", usually it should // contain two subdir: data and wal. const char* getDataRoot() const override { return dataPath_.c_str(); } diff --git a/src/kvstore/plugins/elasticsearch/ESListener.cpp b/src/kvstore/plugins/elasticsearch/ESListener.cpp index 0e59b5227bd..767298d7dbf 100644 --- a/src/kvstore/plugins/elasticsearch/ESListener.cpp +++ b/src/kvstore/plugins/elasticsearch/ESListener.cpp @@ -44,7 +44,7 @@ void ESListener::init() { bool ESListener::apply(const std::vector& data) { std::vector docItems; for (const auto& kv : data) { - if (!nebula::NebulaKeyUtils::isVertex(vIdLen_, kv.first) && + if (!nebula::NebulaKeyUtils::isTag(vIdLen_, kv.first) && !nebula::NebulaKeyUtils::isEdge(vIdLen_, kv.first)) { continue; } @@ -74,7 +74,7 @@ bool ESListener::persist(LogID lastId, TermID lastTerm, LogID lastApplyLogId) { std::pair ESListener::lastCommittedLogId() { if (access(lastApplyLogFile_->c_str(), 0) != 0) { - VLOG(3) << "Invalid or non-existent file : " << *lastApplyLogFile_; + VLOG(3) << "Invalid or nonexistent file : " << *lastApplyLogFile_; return {0, 0}; } int32_t fd = open(lastApplyLogFile_->c_str(), O_RDONLY); @@ -97,7 +97,7 @@ std::pair ESListener::lastCommittedLogId() { LogID ESListener::lastApplyLogId() { if (access(lastApplyLogFile_->c_str(), 0) != 0) { - VLOG(3) << "Invalid or non-existent file : " << *lastApplyLogFile_; + VLOG(3) << "Invalid or nonexistent file : " << *lastApplyLogFile_; return 0; } int32_t fd = open(lastApplyLogFile_->c_str(), O_RDONLY); diff --git a/src/kvstore/plugins/hbase/HBaseStore.cpp b/src/kvstore/plugins/hbase/HBaseStore.cpp index 81d2577ccc2..3d2e55270db 100644 --- a/src/kvstore/plugins/hbase/HBaseStore.cpp +++ b/src/kvstore/plugins/hbase/HBaseStore.cpp @@ -45,7 +45,7 @@ std::shared_ptr HBaseStore::getSchema(GraphSpaceID SchemaVer version) { std::shared_ptr schema; folly::StringPiece rawKey = key; - if (NebulaKeyUtils::isVertex(key)) { + if (NebulaKeyUtils::isTag(key)) { TagID tagId = NebulaKeyUtils::getTagId(rawKey); if (version == -1) { version = schemaMan_->getLatestTagSchemaVersion(spaceId, tagId).value(); diff --git a/src/kvstore/plugins/hbase/HBaseStore.h b/src/kvstore/plugins/hbase/HBaseStore.h index f137f9f8352..3ceff2be77c 100644 --- a/src/kvstore/plugins/hbase/HBaseStore.h +++ b/src/kvstore/plugins/hbase/HBaseStore.h @@ -157,11 +157,11 @@ class HBaseStore : public KVStore { KVCallback cb); void asyncAtomicOp(GraphSpaceID, PartitionID, raftex::AtomicOp, KVCallback) override { - LOG(FATAL) << "Not supportted yet!"; + LOG(FATAL) << "Not supported yet!"; } void asyncAtomicOp(GraphSpaceID, PartitionID, std::string&& multiValues, KVCallback) override { - LOG(FATAL) << "Not supportted yet!"; + LOG(FATAL) << "Not supported yet!"; } ResultCode ingest(GraphSpaceID spaceId) override; diff --git a/src/kvstore/plugins/hbase/hbase.thrift b/src/kvstore/plugins/hbase/hbase.thrift index cfd49df60b9..710a325127d 100644 --- a/src/kvstore/plugins/hbase/hbase.thrift +++ b/src/kvstore/plugins/hbase/hbase.thrift @@ -398,7 +398,7 @@ service THBaseService { 4: binary qualifier, /** the expected value, if not provided the - check is for the non-existence of the + check is for the nonexistence of the column in question */ 5: binary value, @@ -466,7 +466,7 @@ service THBaseService { 4: binary qualifier, /** the expected value, if not provided the - check is for the non-existence of the + check is for the nonexistence of the column in question */ 5: binary value, @@ -613,7 +613,7 @@ service THBaseService { 5: TCompareOp compareOp, /** the expected value to be compared against, if not provided the - check is for the non-existence of the column in question */ + check is for the nonexistence of the column in question */ 6: binary value, /** row mutations to execute if the value matches */ diff --git a/src/kvstore/plugins/hbase/test/HBaseStoreTest.cpp b/src/kvstore/plugins/hbase/test/HBaseStoreTest.cpp index 94fddde5c9e..cf62f839f22 100644 --- a/src/kvstore/plugins/hbase/test/HBaseStoreTest.cpp +++ b/src/kvstore/plugins/hbase/test/HBaseStoreTest.cpp @@ -38,11 +38,11 @@ TEST(HBaseStoreTest, SimpleTest) { EdgeVerPlaceHolder edgeVersion = 1; std::vector edgeKeys; std::vector edgeData; - auto edgeScheam = sm->getEdgeSchema(spaceId, edgeType, edgeVersion); + auto edgeSchema = sm->getEdgeSchema(spaceId, edgeType, edgeVersion); for (auto vertexId = srcId; vertexId < dstId; vertexId++) { auto edgeKey = NebulaKeyUtils::edgeKey(partId, srcId, edgeType, rank, vertexId); edgeKeys.emplace_back(edgeKey); - RowWriter edgeWriter(edgeScheam); + RowWriter edgeWriter(edgeSchema); for (int32_t iInt = 0; iInt < 10; iInt++) { edgeWriter << iInt; } @@ -53,11 +53,11 @@ TEST(HBaseStoreTest, SimpleTest) { edgeData.emplace_back(edgeKey, edgeValue); } - edgeScheam = sm->getEdgeSchema(spaceId, edgeType + 1, edgeVersion); + edgeSchema = sm->getEdgeSchema(spaceId, edgeType + 1, edgeVersion); for (; edgeVersion < 10L; edgeVersion++) { auto edgeKey = NebulaKeyUtils::edgeKey(partId, srcId, edgeType + 1, rank, dstId); edgeKeys.emplace_back(edgeKey); - RowWriter edgeWriter(edgeScheam); + RowWriter edgeWriter(edgeSchema); for (int32_t iInt = 0; iInt < 5; iInt++) { edgeWriter << iInt; } @@ -93,7 +93,7 @@ TEST(HBaseStoreTest, SimpleTest) { } EXPECT_EQ(expectedTotal, num); }; - std::string prefix1 = NebulaKeyUtils::vertexPrefix(partId, srcId); + std::string prefix1 = NebulaKeyUtils::tagPrefix(partId, srcId); checkPrefix(prefix1, 0, 20); std::string prefix2 = NebulaKeyUtils::edgePrefix(partId, srcId, edgeType); checkPrefix(prefix2, 0, 10); diff --git a/src/kvstore/raftex/CMakeLists.txt b/src/kvstore/raftex/CMakeLists.txt index dcb96522dfe..4056e4a47b8 100644 --- a/src/kvstore/raftex/CMakeLists.txt +++ b/src/kvstore/raftex/CMakeLists.txt @@ -1,6 +1,5 @@ nebula_add_library( raftex_obj OBJECT - LogStrListIterator.cpp RaftPart.cpp RaftexService.cpp Host.cpp diff --git a/src/kvstore/raftex/Host.cpp b/src/kvstore/raftex/Host.cpp index 20d8a400050..e57dd9cb6bb 100644 --- a/src/kvstore/raftex/Host.cpp +++ b/src/kvstore/raftex/Host.cpp @@ -50,11 +50,6 @@ cpp2::ErrorCode Host::checkStatus() const { return cpp2::ErrorCode::E_HOST_STOPPED; } - if (paused_) { - VLOG(2) << idStr_ << "The host is paused, due to losing leadership"; - return cpp2::ErrorCode::E_NOT_A_LEADER; - } - return cpp2::ErrorCode::SUCCEEDED; } @@ -70,8 +65,7 @@ folly::Future Host::askForVote(const cpp2::AskForVoteR return resp; } } - auto client = - part_->clientMan_->client(addr_, eb, false, FLAGS_raft_heartbeat_interval_secs * 1000); + auto client = part_->clientMan_->client(addr_, eb, false, FLAGS_raft_rpc_timeout_ms); return client->future_askForVote(req); } @@ -89,23 +83,18 @@ folly::Future Host::appendLogs(folly::EventBase* eb, std::lock_guard g(lock_); auto res = checkStatus(); - if (logId <= lastLogIdSent_) { - LOG(INFO) << idStr_ << "The log " << logId << " has been sended" - << ", lastLogIdSent " << lastLogIdSent_; - cpp2::AppendLogResponse r; - r.set_error_code(cpp2::ErrorCode::SUCCEEDED); - return r; - } - if (requestOnGoing_ && res == cpp2::ErrorCode::SUCCEEDED) { + if (UNLIKELY(sendingSnapshot_)) { + LOG_EVERY_N(INFO, 500) << idStr_ << "The target host is waiting for a snapshot"; + res = cpp2::ErrorCode::E_WAITING_SNAPSHOT; + } else if (requestOnGoing_) { + // buffer incoming request to pendingReq_ if (cachingPromise_.size() <= FLAGS_max_outstanding_requests) { pendingReq_ = std::make_tuple(term, logId, committedLogId); return cachingPromise_.getFuture(); } else { LOG_EVERY_N(INFO, 200) << idStr_ << "Too many requests are waiting, return error"; - cpp2::AppendLogResponse r; - r.set_error_code(cpp2::ErrorCode::E_TOO_MANY_REQUESTS); - return r; + res = cpp2::ErrorCode::E_TOO_MANY_REQUESTS; } } @@ -129,14 +118,23 @@ folly::Future Host::appendLogs(folly::EventBase* eb, logTermToSend_ = term; logIdToSend_ = logId; committedLogId_ = committedLogId; - pendingReq_ = std::make_tuple(0, 0, 0); - promise_ = std::move(cachingPromise_); - cachingPromise_ = folly::SharedPromise(); - ret = promise_.getFuture(); - - requestOnGoing_ = true; - req = prepareAppendLogRequest(); + auto result = prepareAppendLogRequest(); + if (ok(result)) { + LOG_IF(INFO, FLAGS_trace_raft) << idStr_ << "Sending the pending request in the queue" + << ", from " << lastLogIdSent_ + 1 << " to " << logIdToSend_; + req = std::move(value(result)); + pendingReq_ = std::make_tuple(0, 0, 0); + promise_ = std::move(cachingPromise_); + cachingPromise_ = folly::SharedPromise(); + ret = promise_.getFuture(); + requestOnGoing_ = true; + } else { + // target host is waiting for a snapshot or wal not found + cpp2::AppendLogResponse r; + r.set_error_code(error(result)); + return r; + } } // Get a new promise @@ -152,6 +150,7 @@ void Host::setResponse(const cpp2::AppendLogResponse& r) { cachingPromise_ = folly::SharedPromise(); pendingReq_ = std::make_tuple(0, 0, 0); requestOnGoing_ = false; + noMoreRequestCV_.notify_all(); } void Host::appendLogsInternal(folly::EventBase* eb, std::shared_ptr req) { @@ -167,7 +166,9 @@ void Host::appendLogsInternal(folly::EventBase* eb, std::shared_ptrlastLogIdSent_ << ", lastLogTermSent_ " << self->lastLogTermSent_; switch (resp.get_error_code()) { - case cpp2::ErrorCode::SUCCEEDED: { + case cpp2::ErrorCode::SUCCEEDED: + case cpp2::ErrorCode::E_LOG_GAP: + case cpp2::ErrorCode::E_LOG_STALE: { VLOG(2) << self->idStr_ << "AppendLog request sent successfully"; std::shared_ptr newReq; @@ -175,161 +176,44 @@ void Host::appendLogsInternal(folly::EventBase* eb, std::shared_ptr g(self->lock_); auto res = self->checkStatus(); if (res != cpp2::ErrorCode::SUCCEEDED) { - VLOG(2) << self->idStr_ - << "The host is not in a proper status," - " just return"; - cpp2::AppendLogResponse r; - r.set_error_code(res); - self->setResponse(r); - } else if (self->lastLogIdSent_ >= resp.get_last_log_id()) { - VLOG(2) << self->idStr_ << "We send nothing in the last request" - << ", so we don't send the same logs again"; - self->followerCommittedLogId_ = resp.get_committed_log_id(); cpp2::AppendLogResponse r; r.set_error_code(res); self->setResponse(r); - } else { - self->lastLogIdSent_ = resp.get_last_log_id(); - self->lastLogTermSent_ = resp.get_last_log_term(); - self->followerCommittedLogId_ = resp.get_committed_log_id(); - if (self->lastLogIdSent_ < self->logIdToSend_) { - // More to send - VLOG(2) << self->idStr_ << "There are more logs to send"; - newReq = self->prepareAppendLogRequest(); - } else { - VLOG(2) << self->idStr_ - << "Fulfill the promise, size = " << self->promise_.size(); - // Fulfill the promise - self->promise_.setValue(resp); - - if (self->noRequest()) { - VLOG(2) << self->idStr_ << "No request any more!"; - self->requestOnGoing_ = false; - } else { - auto& tup = self->pendingReq_; - self->logTermToSend_ = std::get<0>(tup); - self->logIdToSend_ = std::get<1>(tup); - self->committedLogId_ = std::get<2>(tup); - VLOG(2) << self->idStr_ << "Sending the pending request in the queue" - << ", from " << self->lastLogIdSent_ + 1 << " to " - << self->logIdToSend_; - newReq = self->prepareAppendLogRequest(); - self->promise_ = std::move(self->cachingPromise_); - self->cachingPromise_ = folly::SharedPromise(); - self->pendingReq_ = std::make_tuple(0, 0, 0); - } // self->noRequest() - } // self->lastLogIdSent_ < self->logIdToSend_ - } // else - } - if (newReq) { - self->appendLogsInternal(eb, newReq); - } else { - self->noMoreRequestCV_.notify_all(); - } - return; - } - case cpp2::ErrorCode::E_LOG_GAP: { - VLOG(2) << self->idStr_ << "The host's log is behind, need to catch up"; - std::shared_ptr newReq; - { - std::lock_guard g(self->lock_); - auto res = self->checkStatus(); - if (res != cpp2::ErrorCode::SUCCEEDED) { - VLOG(2) << self->idStr_ - << "The host is not in a proper status," - " skip catching up the gap"; - cpp2::AppendLogResponse r; - r.set_error_code(res); - self->setResponse(r); - } else if (self->lastLogIdSent_ == resp.get_last_log_id()) { - VLOG(2) << self->idStr_ << "We send nothing in the last request" - << ", so we don't send the same logs again"; - self->lastLogIdSent_ = resp.get_last_log_id(); - self->lastLogTermSent_ = resp.get_last_log_term(); - self->followerCommittedLogId_ = resp.get_committed_log_id(); - cpp2::AppendLogResponse r; - r.set_error_code(cpp2::ErrorCode::SUCCEEDED); - self->setResponse(r); - } else { - self->lastLogIdSent_ = std::min(resp.get_last_log_id(), self->logIdToSend_ - 1); - self->lastLogTermSent_ = resp.get_last_log_term(); - self->followerCommittedLogId_ = resp.get_committed_log_id(); - newReq = self->prepareAppendLogRequest(); + return; } - } - if (newReq) { - self->appendLogsInternal(eb, newReq); - } else { - self->noMoreRequestCV_.notify_all(); - } - return; - } - case cpp2::ErrorCode::E_WAITING_SNAPSHOT: { - LOG(INFO) << self->idStr_ - << "The host is waiting for the snapshot, so we need to " - "send log from " - << "current committedLogId " << self->committedLogId_; - std::shared_ptr newReq; - { - std::lock_guard g(self->lock_); - auto res = self->checkStatus(); - if (res != cpp2::ErrorCode::SUCCEEDED) { - VLOG(2) << self->idStr_ - << "The host is not in a proper status," - " skip waiting the snapshot"; - cpp2::AppendLogResponse r; - r.set_error_code(res); - self->setResponse(r); - } else { - self->lastLogIdSent_ = self->committedLogId_; - self->lastLogTermSent_ = self->logTermToSend_; - self->followerCommittedLogId_ = resp.get_committed_log_id(); - newReq = self->prepareAppendLogRequest(); - } - } - if (newReq) { - self->appendLogsInternal(eb, newReq); - } else { - self->noMoreRequestCV_.notify_all(); - } - return; - } - case cpp2::ErrorCode::E_LOG_STALE: { - VLOG(2) << self->idStr_ << "Log stale, reset lastLogIdSent " << self->lastLogIdSent_ - << " to the followers lastLodId " << resp.get_last_log_id(); - std::shared_ptr newReq; - { - std::lock_guard g(self->lock_); - auto res = self->checkStatus(); - if (res != cpp2::ErrorCode::SUCCEEDED) { - VLOG(2) << self->idStr_ - << "The host is not in a proper status," - " skip waiting the snapshot"; - cpp2::AppendLogResponse r; - r.set_error_code(res); - self->setResponse(r); - } else if (self->logIdToSend_ <= resp.get_last_log_id()) { - VLOG(2) << self->idStr_ << "It means the request has been received by follower"; - self->lastLogIdSent_ = self->logIdToSend_ - 1; - self->lastLogTermSent_ = resp.get_last_log_term(); - self->followerCommittedLogId_ = resp.get_committed_log_id(); - cpp2::AppendLogResponse r; - r.set_error_code(cpp2::ErrorCode::SUCCEEDED); - self->setResponse(r); + // Host is working + self->lastLogIdSent_ = resp.get_last_log_id(); + self->lastLogTermSent_ = resp.get_last_log_term(); + self->followerCommittedLogId_ = resp.get_committed_log_id(); + if (self->lastLogIdSent_ < self->logIdToSend_) { + // More to send + VLOG(2) << self->idStr_ << "There are more logs to send"; + auto result = self->prepareAppendLogRequest(); + if (ok(result)) { + newReq = std::move(value(result)); + } else { + cpp2::AppendLogResponse r; + r.set_error_code(error(result)); + self->setResponse(r); + return; + } } else { - self->lastLogIdSent_ = std::min(resp.get_last_log_id(), self->logIdToSend_ - 1); - self->lastLogTermSent_ = resp.get_last_log_term(); - self->followerCommittedLogId_ = resp.get_committed_log_id(); - newReq = self->prepareAppendLogRequest(); + // resp.get_last_log_id() >= self->logIdToSend_ + // All logs up to logIdToSend_ has been sent, fulfill the promise + self->promise_.setValue(resp); + // Check if there are any pending request: + // Eithor send pending requst if any, or set Host to vacant + newReq = self->getPendingReqIfAny(self); } } if (newReq) { self->appendLogsInternal(eb, newReq); - } else { - self->noMoreRequestCV_.notify_all(); } return; } + // Usually the peer is not in proper state, for example: + // E_UNKNOWN_PART/E_BAD_STATE/E_NOT_READY/E_WAITING_SNAPSHOT + // In this case, nothing changed, just return the error default: { LOG_EVERY_N(ERROR, 100) << self->idStr_ << "Failed to append logs to the host (Err: " @@ -337,9 +221,7 @@ void Host::appendLogsInternal(folly::EventBase* eb, std::shared_ptr g(self->lock_); self->setResponse(resp); - self->lastLogIdSent_ = self->logIdToSend_ - 1; } - self->noMoreRequestCV_.notify_all(); return; } } @@ -348,81 +230,77 @@ void Host::appendLogsInternal(folly::EventBase* eb, std::shared_ptridStr_ << ex.what(); cpp2::AppendLogResponse r; - r.set_error_code(cpp2::ErrorCode::E_EXCEPTION); + r.set_error_code(cpp2::ErrorCode::E_RPC_EXCEPTION); { std::lock_guard g(self->lock_); if (ex.getType() == TransportException::TIMED_OUT) { - VLOG(2) << self->idStr_ << "append log time out" - << ", space " << req->get_space() << ", part " << req->get_part() - << ", current term " << req->get_current_term() << ", last_log_id " - << req->get_last_log_id() << ", committed_id " - << req->get_committed_log_id() << ", last_log_term_sent" - << req->get_last_log_term_sent() << ", last_log_id_sent " - << req->get_last_log_id_sent() << ", logs size " - << req->get_log_str_list().size(); + LOG_IF(INFO, FLAGS_trace_raft) + << self->idStr_ << "append log time out" + << ", space " << req->get_space() << ", part " << req->get_part() + << ", current term " << req->get_current_term() << ", last_log_id " + << req->get_last_log_id() << ", committed_id " + << req->get_committed_log_id() << ", last_log_term_sent " + << req->get_last_log_term_sent() << ", last_log_id_sent " + << req->get_last_log_id_sent() << ", set lastLogIdSent_ to logIdToSend_ " + << self->logIdToSend_ << ", logs size " + << req->get_log_str_list().size(); } self->setResponse(r); - self->lastLogIdSent_ = self->logIdToSend_ - 1; } // a new raft log or heartbeat will trigger another appendLogs in Host - self->noMoreRequestCV_.notify_all(); return; }) .thenError(folly::tag_t{}, [self = shared_from_this()](std::exception&& ex) { VLOG(2) << self->idStr_ << ex.what(); cpp2::AppendLogResponse r; - r.set_error_code(cpp2::ErrorCode::E_EXCEPTION); + r.set_error_code(cpp2::ErrorCode::E_RPC_EXCEPTION); { std::lock_guard g(self->lock_); self->setResponse(r); - self->lastLogIdSent_ = self->logIdToSend_ - 1; } // a new raft log or heartbeat will trigger another appendLogs in Host - self->noMoreRequestCV_.notify_all(); return; }); } -std::shared_ptr Host::prepareAppendLogRequest() { +ErrorOr> Host::prepareAppendLogRequest() { CHECK(!lock_.try_lock()); - auto req = std::make_shared(); - req->set_space(part_->spaceId()); - req->set_part(part_->partitionId()); - req->set_current_term(logTermToSend_); - req->set_last_log_id(logIdToSend_); - req->set_leader_addr(part_->address().host); - req->set_leader_port(part_->address().port); - req->set_committed_log_id(committedLogId_); - req->set_last_log_term_sent(lastLogTermSent_); - req->set_last_log_id_sent(lastLogIdSent_); - VLOG(2) << idStr_ << "Prepare AppendLogs request from Log " << lastLogIdSent_ + 1 << " to " << logIdToSend_; if (lastLogIdSent_ + 1 > part_->wal()->lastLogId()) { - LOG(INFO) << idStr_ << "My lastLogId in wal is " << part_->wal()->lastLogId() - << ", but you are seeking " << lastLogIdSent_ + 1 << ", so i have nothing to send."; - return req; + LOG_IF(INFO, FLAGS_trace_raft) + << idStr_ << "My lastLogId in wal is " << part_->wal()->lastLogId() + << ", but you are seeking " << lastLogIdSent_ + 1 + << ", so i have nothing to send, logIdToSend_ = " << logIdToSend_; + return cpp2::ErrorCode::E_NO_WAL_FOUND; } auto it = part_->wal()->iterator(lastLogIdSent_ + 1, logIdToSend_); if (it->valid()) { - VLOG(2) << idStr_ << "Prepare the list of log entries to send"; - auto term = it->logTerm(); + auto req = std::make_shared(); + req->set_space(part_->spaceId()); + req->set_part(part_->partitionId()); + req->set_current_term(logTermToSend_); + req->set_last_log_id(logIdToSend_); + req->set_leader_addr(part_->address().host); + req->set_leader_port(part_->address().port); + req->set_committed_log_id(committedLogId_); + req->set_last_log_term_sent(lastLogTermSent_); + req->set_last_log_id_sent(lastLogIdSent_); req->set_log_term(term); - std::vector logs; + std::vector logs; for (size_t cnt = 0; it->valid() && it->logTerm() == term && cnt < FLAGS_max_appendlog_batch_size; ++(*it), ++cnt) { - cpp2::LogEntry le; + nebula::cpp2::LogEntry le; le.set_cluster(it->logSource()); le.set_log_str(it->logMsg().toString()); logs.emplace_back(std::move(le)); } req->set_log_str_list(std::move(logs)); - req->set_sending_snapshot(false); + return req; } else { - req->set_sending_snapshot(true); if (!sendingSnapshot_) { LOG(INFO) << idStr_ << "Can't find log " << lastLogIdSent_ + 1 << " in wal, send the snapshot" << ", logIdToSend = " << logIdToSend_ @@ -430,21 +308,28 @@ std::shared_ptr Host::prepareAppendLogRequest() { << ", lastLogId in wal = " << part_->wal()->lastLogId(); sendingSnapshot_ = true; part_->snapshot_->sendSnapshot(part_, addr_) - .thenValue([self = shared_from_this()](Status&& status) { + .thenValue([self = shared_from_this()](auto&& status) { + std::lock_guard g(self->lock_); if (status.ok()) { - LOG(INFO) << self->idStr_ << "Send snapshot succeeded!"; + auto commitLogIdAndTerm = status.value(); + self->lastLogIdSent_ = commitLogIdAndTerm.first; + self->lastLogTermSent_ = commitLogIdAndTerm.second; + self->followerCommittedLogId_ = commitLogIdAndTerm.first; + LOG(INFO) << self->idStr_ << "Send snapshot succeeded!" + << " commitLogId = " << commitLogIdAndTerm.first + << " commitLogTerm = " << commitLogIdAndTerm.second; } else { LOG(INFO) << self->idStr_ << "Send snapshot failed!"; // TODO(heng): we should tell the follower i am failed. } self->sendingSnapshot_ = false; + self->noMoreRequestCV_.notify_all(); }); } else { - LOG_EVERY_N(INFO, 30) << idStr_ << "The snapshot req is in queue, please wait for a moment"; + LOG_EVERY_N(INFO, 100) << idStr_ << "The snapshot req is in queue, please wait for a moment"; } + return cpp2::ErrorCode::E_WAITING_SNAPSHOT; } - - return req; } folly::Future Host::sendAppendLogRequest( @@ -466,9 +351,10 @@ folly::Future Host::sendAppendLogRequest( << ", part " << req->get_part() << ", current term " << req->get_current_term() << ", last_log_id " << req->get_last_log_id() << ", committed_id " - << req->get_committed_log_id() << ", last_log_term_sent" + << req->get_committed_log_id() << ", last_log_term_sent " << req->get_last_log_term_sent() << ", last_log_id_sent " - << req->get_last_log_id_sent(); + << req->get_last_log_id_sent() << ", logs in request " + << req->get_log_str_list().size(); // Get client connection auto client = part_->clientMan_->client(addr_, eb, false, FLAGS_raft_rpc_timeout_ms); return client->future_appendLog(*req); @@ -499,7 +385,7 @@ folly::Future Host::sendHeartbeat(folly::EventBase* eb, VLOG(3) << self->idStr_ << "heartbeat call got response"; if (t.hasException()) { cpp2::HeartbeatResponse resp; - resp.set_error_code(cpp2::ErrorCode::E_EXCEPTION); + resp.set_error_code(cpp2::ErrorCode::E_RPC_EXCEPTION); pro.setValue(std::move(resp)); return; } else { @@ -542,5 +428,40 @@ bool Host::noRequest() const { return pendingReq_ == emptyTup; } +std::shared_ptr Host::getPendingReqIfAny(std::shared_ptr self) { + CHECK(!self->lock_.try_lock()); + CHECK(self->requestOnGoing_) << self->idStr_; + + // Check if there are any pending request to send + if (self->noRequest()) { + self->noMoreRequestCV_.notify_all(); + self->requestOnGoing_ = false; + return nullptr; + } + + // there is pending request + auto& tup = self->pendingReq_; + self->logTermToSend_ = std::get<0>(tup); + self->logIdToSend_ = std::get<1>(tup); + self->committedLogId_ = std::get<2>(tup); + + LOG_IF(INFO, FLAGS_trace_raft) << self->idStr_ << "Sending the pending request in the queue" + << ", from " << self->lastLogIdSent_ + 1 << " to " + << self->logIdToSend_; + self->pendingReq_ = std::make_tuple(0, 0, 0); + self->promise_ = std::move(self->cachingPromise_); + self->cachingPromise_ = folly::SharedPromise(); + + auto result = self->prepareAppendLogRequest(); + if (ok(result)) { + return value(result); + } else { + cpp2::AppendLogResponse r; + r.set_error_code(error(result)); + self->setResponse(r); + return nullptr; + } +} + } // namespace raftex } // namespace nebula diff --git a/src/kvstore/raftex/Host.h b/src/kvstore/raftex/Host.h index 3cc23ef0ad8..db52bee54ec 100644 --- a/src/kvstore/raftex/Host.h +++ b/src/kvstore/raftex/Host.h @@ -9,6 +9,7 @@ #include #include "common/base/Base.h" +#include "common/base/ErrorOr.h" #include "common/thrift/ThriftClientManager.h" #include "interface/gen-cpp2/RaftexServiceAsyncClient.h" #include "interface/gen-cpp2/raftex_types.h" @@ -32,18 +33,6 @@ class Host final : public std::enable_shared_from_this { const char* idStr() const { return idStr_.c_str(); } - // This will be called when the shard lost its leadership - void pause() { - std::lock_guard g(lock_); - paused_ = true; - } - - // This will be called when the shard becomes the leader - void resume() { - std::lock_guard g(lock_); - paused_ = false; - } - void stop() { std::lock_guard g(lock_); stopped_ = true; @@ -99,12 +88,14 @@ class Host final : public std::enable_shared_from_this { folly::Future sendHeartbeatRequest( folly::EventBase* eb, std::shared_ptr req); - std::shared_ptr prepareAppendLogRequest(); + ErrorOr> prepareAppendLogRequest(); bool noRequest() const; void setResponse(const cpp2::AppendLogResponse& r); + std::shared_ptr getPendingReqIfAny(std::shared_ptr self); + private: // using Request = std::tuple; @@ -116,10 +107,13 @@ class Host final : public std::enable_shared_from_this { mutable std::mutex lock_; - bool paused_{false}; bool stopped_{false}; + // whether there is a batch of logs for target host in on going bool requestOnGoing_{false}; + // whether there is a snapshot for target host in on going + bool sendingSnapshot_{false}; + std::condition_variable noMoreRequestCV_; folly::SharedPromise promise_; folly::SharedPromise cachingPromise_; @@ -135,7 +129,6 @@ class Host final : public std::enable_shared_from_this { TermID lastLogTermSent_{0}; LogID committedLogId_{0}; - std::atomic_bool sendingSnapshot_{false}; // CommittedLogId of follower LogID followerCommittedLogId_{0}; diff --git a/src/kvstore/raftex/RaftPart.cpp b/src/kvstore/raftex/RaftPart.cpp index 9e2db03be09..17b666488cb 100644 --- a/src/kvstore/raftex/RaftPart.cpp +++ b/src/kvstore/raftex/RaftPart.cpp @@ -17,10 +17,10 @@ #include "common/thread/NamedThread.h" #include "common/thrift/ThriftClientManager.h" #include "common/time/WallClock.h" +#include "common/utils/LogStrListIterator.h" #include "interface/gen-cpp2/RaftexServiceAsyncClient.h" #include "kvstore/LogEncoder.h" #include "kvstore/raftex/Host.h" -#include "kvstore/raftex/LogStrListIterator.h" #include "kvstore/wal/FileBasedWal.h" DEFINE_uint32(raft_heartbeat_interval_secs, 5, "Seconds between each heartbeat"); @@ -75,6 +75,8 @@ class AppendLogsIterator final : public LogIterator { LogID firstLogId() const { return firstLogId_; } + LogID lastLogId() const { return firstLogId_ + logs_.size() - 1; } + // Return true if the current log is a AtomicOp, otherwise return false bool processAtomicOp() { while (idx_ < logs_.size()) { @@ -305,7 +307,7 @@ void RaftPart::stop() { decltype(hosts_) hosts; { - std::unique_lock lck(raftLock_); + std::lock_guard lck(raftLock_); status_ = Status::STOPPED; leader_ = {"", 0}; role_ = Role::FOLLOWER; @@ -378,11 +380,11 @@ void RaftPart::preProcessTransLeader(const HostAddr& target) { LOG(INFO) << idStr_ << "I will be the new leader, trigger leader election now!"; bgWorkers_->addTask([self = shared_from_this()] { { - std::unique_lock lck(self->raftLock_); + std::lock_guard lck(self->raftLock_); self->role_ = Role::CANDIDATE; self->leader_ = HostAddr("", 0); } - self->leaderElection(); + self->leaderElection().get(); }); } break; @@ -661,7 +663,7 @@ folly::Future RaftPart::appendLogAsync(ClusterID source, } if (!checkAppendLogResult(res)) { - // Mosy likely failed because the parttion is not leader + // Mosy likely failed because the partition is not leader LOG_EVERY_N(WARNING, 1000) << idStr_ << "Cannot append logs, clean the buffer"; return res; } @@ -697,7 +699,7 @@ void RaftPart::appendLogsInternal(AppendLogsIterator iter, TermID termId) { VLOG(2) << idStr_ << "Ready to append logs from id " << iter.logId() << " (Current term is " << currTerm << ")"; } else { - LOG(ERROR) << idStr_ << "Only happend when Atomic op failed"; + LOG(ERROR) << idStr_ << "Only happened when Atomic op failed"; replicatingLogs_ = false; return; } @@ -762,7 +764,8 @@ void RaftPart::replicateLogs(folly::EventBase* eb, return; } - VLOG(2) << idStr_ << "About to replicate logs to all peer hosts"; + LOG_IF(INFO, FLAGS_trace_raft) << idStr_ << "About to replicate logs in range [" + << iter.firstLogId() << ", " << lastLogId << "] to all peer hosts"; lastMsgSentDur_.reset(); SlowOpTracker tracker; @@ -973,21 +976,6 @@ bool RaftPart::prepareElectionRequest(cpp2::AskForVoteRequest& req, return false; } - if (UNLIKELY(status_ == Status::STOPPED)) { - VLOG(2) << idStr_ << "The part has been stopped, skip the request"; - return false; - } - - if (UNLIKELY(status_ == Status::STARTING)) { - VLOG(2) << idStr_ << "The partition is still starting"; - return false; - } - - if (UNLIKELY(status_ == Status::WAITING_SNAPSHOT)) { - VLOG(2) << idStr_ << "The partition is still waiting snapshot"; - return false; - } - // Make sure the role is still CANDIDATE if (role_ != Role::CANDIDATE) { VLOG(2) << idStr_ << "A leader has been elected"; @@ -1027,7 +1015,7 @@ typename RaftPart::Role RaftPart::processElectionResponses( } if (UNLIKELY(status_ == Status::WAITING_SNAPSHOT)) { - LOG(INFO) << idStr_ << "The partition is still waitiong snapshot"; + LOG(INFO) << idStr_ << "The partition is still waiting snapshot"; return role_; } @@ -1065,15 +1053,15 @@ typename RaftPart::Role RaftPart::processElectionResponses( return role_; } -bool RaftPart::leaderElection() { +folly::Future RaftPart::leaderElection() { VLOG(2) << idStr_ << "Start leader election..."; using namespace folly; // NOLINT since the fancy overload of | operator bool expected = false; + if (!inElection_.compare_exchange_strong(expected, true)) { - return true; + return false; } - SCOPE_EXIT { inElection_ = false; }; cpp2::AskForVoteRequest voteReq; decltype(hosts_) hosts; @@ -1083,11 +1071,12 @@ bool RaftPart::leaderElection() { // and need the snapshot from B. Meanwhile C begin the election, // C will be Candidate, but because C is in WAITING_SNAPSHOT, // so prepareElectionRequest will return false and go on the election. - // Becasue C is in Candidate, so it will reject the snapshot request from B. + // Because C is in Candidate, so it will reject the snapshot request from B. // Infinite loop begins. - // So we neeed to go back to the follower state to avoid the case. + // So we need to go back to the follower state to avoid the case. std::lock_guard g(raftLock_); role_ = Role::FOLLOWER; + inElection_ = false; return false; } @@ -1102,53 +1091,66 @@ bool RaftPart::leaderElection() { auto proposedTerm = voteReq.get_term(); auto resps = ElectionResponses(); if (hosts.empty()) { - VLOG(2) << idStr_ << "No peer found, I will be the leader"; + auto ret = handleElectionResponses(resps, hosts, proposedTerm); + inElection_ = false; + return ret; } else { + folly::Promise promise; + auto future = promise.getFuture(); auto eb = ioThreadPool_->getEventBase(); - auto futures = collectNSucceeded( - gen::from(hosts) | gen::map([eb, self = shared_from_this(), &voteReq](auto& host) { - VLOG(2) << self->idStr_ << "Sending AskForVoteRequest to " << host->idStr(); - return via(eb, [&voteReq, &host, eb]() -> Future { - return host->askForVote(voteReq, eb); - }); - }) | gen::as(), + collectNSucceeded( + gen::from(hosts) | + gen::map([eb, self = shared_from_this(), voteReq](std::shared_ptr host) { + VLOG(2) << self->idStr_ << "Sending AskForVoteRequest to " << host->idStr(); + return via(eb, [voteReq, host, eb]() -> Future { + return host->askForVote(voteReq, eb); + }); + }) | + gen::as(), // Number of succeeded required quorum_, // Result evaluator [hosts](size_t idx, cpp2::AskForVoteResponse& resp) { return resp.get_error_code() == cpp2::ErrorCode::SUCCEEDED && !hosts[idx]->isLearner(); + }) + .via(executor_.get()) + .then([self = shared_from_this(), pro = std::move(promise), hosts, proposedTerm]( + auto&& t) mutable { + VLOG(2) << self->idStr_ + << "AskForVoteRequest has been sent to all peers, waiting for responses"; + CHECK(!t.hasException()); + pro.setValue(self->handleElectionResponses(t.value(), std::move(hosts), proposedTerm)); + self->inElection_ = false; }); - - VLOG(2) << idStr_ - << "AskForVoteRequest has been sent to all peers" - ", waiting for responses"; - futures.wait(); - CHECK(!futures.hasException()) - << "Got exception -- " << futures.result().exception().what().toStdString(); - VLOG(2) << idStr_ << "Got AskForVote response back"; - - resps = std::move(futures).get(); + return future; } +} +bool RaftPart::handleElectionResponses(const ElectionResponses& resps, + const std::vector>& peers, + TermID proposedTerm) { // Process the responses - switch (processElectionResponses(resps, std::move(hosts), proposedTerm)) { + switch (processElectionResponses(resps, std::move(peers), proposedTerm)) { case Role::LEADER: { // Elected LOG(INFO) << idStr_ << "The partition is elected as the leader"; + std::vector> hosts; { std::lock_guard g(raftLock_); if (status_ == Status::RUNNING) { leader_ = addr_; - for (auto& host : hosts_) { - host->reset(); - } + hosts = hosts_; bgWorkers_->addTask( - [self = shared_from_this(), term = voteReq.get_term()] { self->onElected(term); }); + [self = shared_from_this(), proposedTerm] { self->onElected(proposedTerm); }); lastMsgAcceptedTime_ = 0; } weight_ = 1; commitInThisTerm_ = false; } + // reset host can't be executed with raftLock_, otherwise it may encounter deadlock + for (auto& host : hosts) { + host->reset(); + } sendHeartbeat(); return true; } @@ -1184,11 +1186,11 @@ void RaftPart::statusPolling(int64_t startTime) { } size_t delay = FLAGS_raft_heartbeat_interval_secs * 1000 / 3; if (needToStartElection()) { - if (leaderElection()) { + if (leaderElection().get()) { VLOG(2) << idStr_ << "Stop the election"; } else { // No leader has been elected, need to continue - // (After sleeping a random period betwen [500ms, 2s]) + // (After sleeping a random period between [500ms, 2s]) VLOG(2) << idStr_ << "Wait for a while and continue the leader election"; delay = (folly::Random::rand32(1500) + 500) * weight_; } @@ -1197,7 +1199,6 @@ void RaftPart::statusPolling(int64_t startTime) { sendHeartbeat(); } if (needToCleanupSnapshot()) { - LOG(INFO) << idStr_ << "Clean up the snapshot"; cleanupSnapshot(); } { @@ -1238,7 +1239,7 @@ bool RaftPart::needToCleanWal() { void RaftPart::processAskForVoteRequest(const cpp2::AskForVoteRequest& req, cpp2::AskForVoteResponse& resp) { - LOG(INFO) << idStr_ << "Recieved a VOTING request" + LOG(INFO) << idStr_ << "Received a VOTING request" << ": space = " << req.get_space() << ", partition = " << req.get_part() << ", candidateAddr = " << req.get_candidate_addr() << ":" << req.get_candidate_port() << ", term = " << req.get_term() << ", lastLogId = " << req.get_last_log_id() @@ -1261,7 +1262,7 @@ void RaftPart::processAskForVoteRequest(const cpp2::AskForVoteRequest& req, if (UNLIKELY(status_ == Status::WAITING_SNAPSHOT)) { LOG(INFO) << idStr_ << "The partition is still waiting snapshot"; - resp.set_error_code(cpp2::ErrorCode::E_NOT_READY); + resp.set_error_code(cpp2::ErrorCode::E_WAITING_SNAPSHOT); return; } @@ -1331,7 +1332,7 @@ void RaftPart::processAskForVoteRequest(const cpp2::AskForVoteRequest& req, // Before change role from leader to follower, check the logs locally. if (role_ == Role::LEADER && wal_->lastLogId() > lastLogId_) { - LOG(INFO) << idStr_ << "There is one log " << wal_->lastLogId() + LOG(INFO) << idStr_ << "There are some logs up to " << wal_->lastLogId() << " i did not commit when i was leader, rollback to " << lastLogId_; wal_->rollbackToLog(lastLogId_); } @@ -1364,11 +1365,11 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req, << ", lastLogTermSent = " << req.get_last_log_term_sent() << ", num_logs = " << req.get_log_str_list().size() << ", logTerm = " << req.get_log_term() - << ", sendingSnapshot = " << req.get_sending_snapshot() << ", local lastLogId = " << lastLogId_ << ", local lastLogTerm = " << lastLogTerm_ << ", local committedLogId = " << committedLogId_ - << ", local current term = " << term_; + << ", local current term = " << term_ + << ", wal lastLogId = " << wal_->lastLogId(); std::lock_guard g(raftLock_); resp.set_current_term(term_); @@ -1389,6 +1390,11 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req, resp.set_error_code(cpp2::ErrorCode::E_NOT_READY); return; } + if (UNLIKELY(status_ == Status::WAITING_SNAPSHOT)) { + VLOG(2) << idStr_ << "The partition is waiting for snapshot"; + resp.set_error_code(cpp2::ErrorCode::E_WAITING_SNAPSHOT); + return; + } // Check leadership cpp2::ErrorCode err = verifyLeader(req); if (err != cpp2::ErrorCode::SUCCEEDED) { @@ -1401,54 +1407,6 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req, // Reset the timeout timer lastMsgRecvDur_.reset(); - if (req.get_sending_snapshot() && status_ != Status::WAITING_SNAPSHOT) { - LOG(INFO) << idStr_ << "Begin to wait for the snapshot" - << " " << req.get_committed_log_id(); - reset(); - status_ = Status::WAITING_SNAPSHOT; - resp.set_error_code(cpp2::ErrorCode::E_WAITING_SNAPSHOT); - return; - } - - if (UNLIKELY(status_ == Status::WAITING_SNAPSHOT)) { - VLOG(2) << idStr_ << "The part is receiving snapshot," - << "so just accept the new wals, but don't commit them." - << "last_log_id_sent " << req.get_last_log_id_sent() << ", total log number " - << req.get_log_str_list().size(); - if (lastLogId_ > 0 && req.get_last_log_id_sent() > lastLogId_) { - // There is a gap - LOG(INFO) << idStr_ << "Local is missing logs from id " << lastLogId_ << ". Need to catch up"; - resp.set_error_code(cpp2::ErrorCode::E_LOG_GAP); - return; - } - // TODO(heng): if we have 3 node, one is leader, one is wait snapshot and - // return success, the other is follower, but leader replica log to follow - // failed, How to deal with leader crash? At this time, no leader will be - // elected. - size_t numLogs = req.get_log_str_list().size(); - LogID firstId = req.get_last_log_id_sent() + 1; - - VLOG(2) << idStr_ << "Writing log [" << firstId << ", " << firstId + numLogs - 1 << "] to WAL"; - LogStrListIterator iter(firstId, req.get_log_term(), req.get_log_str_list()); - if (wal_->appendLogs(iter)) { - // When leader has been sending a snapshot already, sometimes it would - // send a request with empty log list, and lastLogId in wal may be 0 - // because of reset. - if (numLogs != 0) { - CHECK_EQ(firstId + numLogs - 1, wal_->lastLogId()) << "First Id is " << firstId; - } - lastLogId_ = wal_->lastLogId(); - lastLogTerm_ = wal_->lastLogTerm(); - resp.set_last_log_id(lastLogId_); - resp.set_last_log_term(lastLogTerm_); - resp.set_error_code(cpp2::ErrorCode::SUCCEEDED); - } else { - LOG_EVERY_N(WARNING, 100) << idStr_ << "Failed to append logs to WAL"; - resp.set_error_code(cpp2::ErrorCode::E_WAL_FAIL); - } - return; - } - if (req.get_last_log_id_sent() < committedLogId_ && req.get_last_log_term_sent() <= term_) { LOG(INFO) << idStr_ << "Stale log! The log " << req.get_last_log_id_sent() << ", term " << req.get_last_log_term_sent() << " i had committed yet. My committedLogId is " @@ -1460,7 +1418,7 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req, << ", the log term is " << req.get_last_log_term_sent() << ", but my committedLogId is " << committedLogId_ << ", my term is " << term_ << ", to make the cluster stable i will follow the high term" - << " candidate and clenaup my data"; + << " candidate and cleanup my data"; reset(); resp.set_committed_log_id(committedLogId_); resp.set_last_log_id(lastLogId_); @@ -1469,64 +1427,101 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req, } // req.get_last_log_id_sent() >= committedLogId_ - if (lastLogTerm_ > 0 && req.get_last_log_term_sent() != lastLogTerm_) { - LOG(INFO) << idStr_ << "The local last log term is " << lastLogTerm_ - << ", which is different from the leader's prevLogTerm " - << req.get_last_log_term_sent() << ", the prevLogId is " << req.get_last_log_id_sent() - << ". So need to rollback to last committedLogId_ " << committedLogId_; - if (wal_->rollbackToLog(committedLogId_)) { - lastLogId_ = wal_->lastLogId(); - lastLogTerm_ = wal_->lastLogTerm(); - resp.set_last_log_id(lastLogId_); - resp.set_last_log_term(lastLogTerm_); - LOG(INFO) << idStr_ << "Rollback succeeded! lastLogId is " << lastLogId_ << ", logLogTerm is " - << lastLogTerm_ << ", committedLogId is " << committedLogId_ << ", term is " - << term_; - } - resp.set_error_code(cpp2::ErrorCode::E_LOG_GAP); - return; + if (req.get_last_log_id_sent() == lastLogId_ && req.get_last_log_term_sent() == lastLogTerm_) { + // nothing to do + // just append log later } else if (req.get_last_log_id_sent() > lastLogId_) { // There is a gap LOG(INFO) << idStr_ << "Local is missing logs from id " << lastLogId_ << ". Need to catch up"; resp.set_error_code(cpp2::ErrorCode::E_LOG_GAP); return; - } else if (req.get_last_log_id_sent() < lastLogId_) { - // TODO(doodle): This is a potential bug which would cause data not in - // consensus. In most case, we would hit this path when leader append logs - // to follower and timeout (leader would set lastLogIdSent_ = logIdToSend_ - - // 1 in Host). **But follower actually received it successfully**. Which - // will explain when leader retry to append these logs, the LOG belows is - // printed, and lastLogId_ == req.get_last_log_id_sent() + 1 in the LOG. - // - // In fact we should always rollback to req.get_last_log_id_sent(), and - // append the logs from leader (we can't make promise that the logs in range - // [req.get_last_log_id_sent() + 1, lastLogId_] is same with follower). - // However, this makes no difference in the above case. - LOG(INFO) << idStr_ << "Stale log! Local lastLogId " << lastLogId_ << ", lastLogTerm " - << lastLogTerm_ << ", lastLogIdSent " << req.get_last_log_id_sent() - << ", lastLogTermSent " << req.get_last_log_term_sent(); - resp.set_error_code(cpp2::ErrorCode::E_LOG_STALE); - return; + } else { + // check the last log term is matched or not + int reqLastLogTerm = wal_->getLogTerm(req.get_last_log_id_sent()); + if (req.get_last_log_term_sent() != reqLastLogTerm) { + LOG(INFO) << idStr_ << "The local log term is " << reqLastLogTerm + << ", which is different from the leader's prevLogTerm " + << req.get_last_log_term_sent() << ", the prevLogId is " + << req.get_last_log_id_sent() << ". So ask leader to send logs from committedLogId " + << committedLogId_; + TermID committedLogTerm = wal_->getLogTerm(committedLogId_); + if (committedLogTerm > 0) { + resp.set_last_log_id(committedLogId_); + resp.set_last_log_term(committedLogTerm); + } + resp.set_error_code(cpp2::ErrorCode::E_LOG_GAP); + return; + } } - // Append new logs + // request get_last_log_term_sent == wal[get_last_log_id_sent].log_term size_t numLogs = req.get_log_str_list().size(); LogID firstId = req.get_last_log_id_sent() + 1; - VLOG(2) << idStr_ << "Writing log [" << firstId << ", " << firstId + numLogs - 1 << "] to WAL"; - LogStrListIterator iter(firstId, req.get_log_term(), req.get_log_str_list()); - if (wal_->appendLogs(iter)) { - if (numLogs != 0) { - CHECK_EQ(firstId + numLogs - 1, wal_->lastLogId()) << "First Id is " << firstId; + + size_t diffIndex = 0; + do { + // find the first id/term not match, rollback until it, and append the remaining wal + if (!(req.get_last_log_id_sent() == lastLogId_ && + req.get_last_log_term_sent() == lastLogTerm_)) { + // check the diff index in log, find the first log which term is not same as term in request + { + std::unique_ptr it = wal_->iterator(firstId, firstId + numLogs - 1); + for (size_t i = 0; i < numLogs && it->valid(); i++, ++(*it), diffIndex++) { + int logTerm = it->logTerm(); + if (req.get_log_term() != logTerm) { + break; + } + } + } + + // stale log + if (diffIndex == numLogs) { + // All logs have been received before + resp.set_last_log_id(firstId + numLogs - 1); + resp.set_last_log_term(req.get_log_term()); + // nothing to append, goto commit + break; + } + + // rollback the wal + if (wal_->rollbackToLog(firstId + diffIndex - 1)) { + lastLogId_ = wal_->lastLogId(); + lastLogTerm_ = wal_->lastLogTerm(); + LOG(INFO) << idStr_ << "Rollback succeeded! lastLogId is " << lastLogId_ + << ", logLogTerm is " << lastLogTerm_ << ", committedLogId is " << committedLogId_ + << ", logs in request " << numLogs << ", remaining logs after rollback " + << numLogs - diffIndex; + } else { + LOG(ERROR) << idStr_ << "Rollback fail! lastLogId is" << lastLogId_ << ", logLogTerm is " + << lastLogTerm_ << ", committedLogId is " << committedLogId_ + << ", rollback id is " << firstId + diffIndex - 1; + resp.set_error_code(cpp2::ErrorCode::E_WAL_FAIL); + return; + } + + // update msg + firstId = firstId + diffIndex; + numLogs = numLogs - diffIndex; } - lastLogId_ = wal_->lastLogId(); - lastLogTerm_ = wal_->lastLogTerm(); - resp.set_last_log_id(lastLogId_); - resp.set_last_log_term(lastLogTerm_); - } else { - LOG_EVERY_N(WARNING, 100) << idStr_ << "Failed to append logs to WAL"; - resp.set_error_code(cpp2::ErrorCode::E_WAL_FAIL); - return; - } + + // Append new logs + std::vector logEntries = std::vector( + std::make_move_iterator(req.get_log_str_list().begin() + diffIndex), + std::make_move_iterator(req.get_log_str_list().end())); + LogStrListIterator iter(firstId, req.get_log_term(), std::move(logEntries)); + if (wal_->appendLogs(iter)) { + if (numLogs != 0) { + CHECK_EQ(firstId + numLogs - 1, wal_->lastLogId()) << "First Id is " << firstId; + } + lastLogId_ = wal_->lastLogId(); + lastLogTerm_ = wal_->lastLogTerm(); + resp.set_last_log_id(lastLogId_); + resp.set_last_log_term(lastLogTerm_); + } else { + resp.set_error_code(cpp2::ErrorCode::E_WAL_FAIL); + return; + } + } while (false); LogID lastLogIdCanCommit = std::min(lastLogId_, req.get_committed_log_id()); if (lastLogIdCanCommit > committedLogId_) { @@ -1544,7 +1539,7 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req, } else if (code == nebula::cpp2::ErrorCode::E_WRITE_STALLED) { VLOG(1) << idStr_ << "Follower delay committing log " << committedLogId_ + 1 << " to " << lastLogIdCanCommit; - // Even if log is not applied to state machine, still regard as succeded: + // Even if log is not applied to state machine, still regard as succeeded: // 1. As a follower, upcoming request will try to commit them // 2. If it is elected as leader later, it will try to commit them as well resp.set_committed_log_id(committedLogId_); @@ -1579,7 +1574,7 @@ cpp2::ErrorCode RaftPart::verifyLeader(const REQ& req) { << ". The local term is " << term_ << ". The remote term is not newer"; return cpp2::ErrorCode::E_TERM_OUT_OF_DATE; } else if (req.get_current_term() > term_) { - // Leader stickness, no matter the term in Request is larger or not. + // Leader stickiness, no matter the term in Request is larger or not. // TODO(heng) Maybe we should reconsider the logic if (leader_ != HostAddr("", 0) && leader_ != candidate && lastMsgRecvDur_.elapsedInMSec() < FLAGS_raft_heartbeat_interval_secs * 1000) { @@ -1738,14 +1733,12 @@ void RaftPart::processSendSnapshotRequest(const cpp2::SendSnapshotRequest& req, } if (req.get_done()) { committedLogId_ = req.get_committed_log_id(); - if (lastLogId_ < committedLogId_) { - lastLogId_ = committedLogId_; - lastLogTerm_ = req.get_committed_log_term(); - } - if (wal_->lastLogId() <= committedLogId_) { - LOG(INFO) << idStr_ << "Reset invalid wal after snapshot received"; - wal_->reset(); - } + lastLogId_ = committedLogId_; + lastLogTerm_ = req.get_committed_log_term(); + term_ = proposedTerm_ = lastLogTerm_; + // there should be no wal after state converts to WAITING_SNAPSHOT, the RaftPart has been reset + DCHECK_EQ(wal_->firstLogId(), 0); + DCHECK_EQ(wal_->lastLogId(), 0); status_ = Status::RUNNING; LOG(INFO) << idStr_ << "Receive all snapshot, committedLogId_ " << committedLogId_ << ", lastLodId " << lastLogId_ << ", lastLogTermId " << lastLogTerm_; diff --git a/src/kvstore/raftex/RaftPart.h b/src/kvstore/raftex/RaftPart.h index 437afdbaead..a67fc0123c6 100644 --- a/src/kvstore/raftex/RaftPart.h +++ b/src/kvstore/raftex/RaftPart.h @@ -212,7 +212,7 @@ class RaftPart : public std::enable_shared_from_this { bool needToCleanWal(); - // leader + follwers + // leader + followers std::vector peers() const; std::set listeners() const; @@ -303,7 +303,7 @@ class RaftPart : public std::enable_shared_from_this { private: // A list of // idx -- the index of the peer - // resp -- coresponding response of peer[index] + // resp -- corresponding response of peer[index] using ElectionResponses = std::vector>; using AppendLogResponses = std::vector>; using HeartbeatResponses = std::vector>; @@ -344,8 +344,9 @@ class RaftPart : public std::enable_shared_from_this { void cleanupSnapshot(); // The method sends out AskForVote request - // It return true if a leader is elected, otherwise returns false - bool leaderElection(); + // Return true if a leader is elected (the leader could be self or others), + // otherwise returns false + folly::Future leaderElection(); // The method will fill up the request object and return TRUE // if the election should continue. Otherwise the method will @@ -353,6 +354,11 @@ class RaftPart : public std::enable_shared_from_this { bool prepareElectionRequest(cpp2::AskForVoteRequest& req, std::vector>& hosts); + // return true if elected as the leader, else return false + bool handleElectionResponses(const ElectionResponses& resps, + const std::vector>& hosts, + TermID proposedTerm); + // The method returns the partition's role after the election Role processElectionResponses(const ElectionResponses& results, std::vector> hosts, diff --git a/src/kvstore/raftex/SnapshotManager.cpp b/src/kvstore/raftex/SnapshotManager.cpp index 20f1f31715e..b6a3adc268f 100644 --- a/src/kvstore/raftex/SnapshotManager.cpp +++ b/src/kvstore/raftex/SnapshotManager.cpp @@ -26,9 +26,9 @@ SnapshotManager::SnapshotManager() { std::make_shared("snapshot-ioexecutor"))); } -folly::Future SnapshotManager::sendSnapshot(std::shared_ptr part, - const HostAddr& dst) { - folly::Promise p; +folly::Future>> SnapshotManager::sendSnapshot( + std::shared_ptr part, const HostAddr& dst) { + folly::Promise>> p; auto fut = p.getFuture(); executor_->add([this, p = std::move(p), part, dst]() mutable { auto spaceId = part->spaceId_; @@ -40,7 +40,7 @@ folly::Future SnapshotManager::sendSnapshot(std::shared_ptr pa auto commitLogIdAndTerm = part->lastCommittedLogId(); const auto& localhost = part->address(); std::vector> results; - LOG(INFO) << part->idStr_ << "Begin to send the snapshot" + LOG(INFO) << part->idStr_ << "Begin to send the snapshot to the host " << dst << ", commitLogId = " << commitLogIdAndTerm.first << ", commitLogTerm = " << commitLogIdAndTerm.second; accessAllRowsInSnapshot( @@ -77,7 +77,7 @@ folly::Future SnapshotManager::sendSnapshot(std::shared_ptr pa if (status == SnapshotStatus::DONE) { LOG(INFO) << part->idStr_ << "Finished, totalCount " << totalCount << ", totalSize " << totalSize; - p.setValue(Status::OK()); + p.setValue(commitLogIdAndTerm); } return true; } else { @@ -90,6 +90,7 @@ folly::Future SnapshotManager::sendSnapshot(std::shared_ptr pa } catch (const std::exception& e) { LOG(ERROR) << part->idStr_ << "Send snapshot failed, exception " << e.what() << ", retry " << retry << " times"; + sleep(1); continue; } } diff --git a/src/kvstore/raftex/SnapshotManager.h b/src/kvstore/raftex/SnapshotManager.h index a7c40ac3527..de613caaa6f 100644 --- a/src/kvstore/raftex/SnapshotManager.h +++ b/src/kvstore/raftex/SnapshotManager.h @@ -38,7 +38,8 @@ class SnapshotManager { virtual ~SnapshotManager() = default; // Send snapshot for spaceId, partId to host dst. - folly::Future sendSnapshot(std::shared_ptr part, const HostAddr& dst); + folly::Future>> sendSnapshot(std::shared_ptr part, + const HostAddr& dst); private: folly::Future send(GraphSpaceID spaceId, diff --git a/src/kvstore/raftex/test/CMakeLists.txt b/src/kvstore/raftex/test/CMakeLists.txt index c40b29720c3..40982da8a59 100644 --- a/src/kvstore/raftex/test/CMakeLists.txt +++ b/src/kvstore/raftex/test/CMakeLists.txt @@ -2,8 +2,10 @@ set(RAFTEX_TEST_LIBS $ $ $ + $ $ $ + $ $ $ $ @@ -124,21 +126,6 @@ nebula_add_test( gtest ) -nebula_add_test( - NAME - snapshot_test - SOURCES - SnapshotTest.cpp - RaftexTestBase.cpp - TestShard.cpp - OBJECTS - ${RAFTEX_TEST_LIBS} - LIBRARIES - ${THRIFT_LIBRARIES} - wangle - gtest -) - nebula_add_test( NAME member_change_test diff --git a/src/kvstore/raftex/test/LeaderElectionTest.cpp b/src/kvstore/raftex/test/LeaderElectionTest.cpp index 0b024924092..d5fda35ba98 100644 --- a/src/kvstore/raftex/test/LeaderElectionTest.cpp +++ b/src/kvstore/raftex/test/LeaderElectionTest.cpp @@ -110,7 +110,7 @@ TEST(LeaderElection, LeaderCrash) { services[idx]->addPartition(copies.back()); copies.back()->start(getPeers(allHosts, allHosts[idx])); - // Wait untill all copies agree on the same leader + // Wait until all copies agree on the same leader waitUntilLeaderElected(copies, leader); // Check all hosts agree on the same leader diff --git a/src/kvstore/raftex/test/LogAppendTest.cpp b/src/kvstore/raftex/test/LogAppendTest.cpp index 5b2396a29bd..4e3fc92d791 100644 --- a/src/kvstore/raftex/test/LogAppendTest.cpp +++ b/src/kvstore/raftex/test/LogAppendTest.cpp @@ -91,7 +91,7 @@ TEST(LogAppend, MultiThreadAppend) { if (fut.isReady() && fut.value() == AppendLogResult::E_BUFFER_OVERFLOW) { LOG(FATAL) << "Should not reach here"; } else if (j == numLogs) { - // Only wait on the last log messaage + // Only wait on the last log message ASSERT_EQ(AppendLogResult::SUCCEEDED, std::move(fut).get()); } break; diff --git a/src/kvstore/raftex/test/RaftCase.cpp b/src/kvstore/raftex/test/RaftCase.cpp index 89f5f00414f..42855cf0d81 100644 --- a/src/kvstore/raftex/test/RaftCase.cpp +++ b/src/kvstore/raftex/test/RaftCase.cpp @@ -38,7 +38,7 @@ TEST_F(ThreeRaftTest, LeaderCrashReboot) { size_t idx = leader_->index(); killOneCopy(services_, copies_, leader_, idx); - // Wait untill all copies agree on the same leader_ + // Wait until all copies agree on the same leader_ waitUntilLeaderElected(copies_, leader_); // Check all hosts agree on the same leader_ checkLeadership(copies_, leader_); @@ -112,7 +112,7 @@ TEST_F(ThreeRaftTest, LeaderCrashRebootWithLogs) { killOneCopy(services_, copies_, leader_, leader_->index()); LOG(INFO) << "=====> Wait until leader of term 2 elected"; - // Wait untill all copies agree on the same leader_ + // Wait until all copies agree on the same leader_ waitUntilLeaderElected(copies_, leader_); auto leader2 = leader_; ASSERT_NE(leader1, leader2); diff --git a/src/kvstore/raftex/test/RaftexTestBase.cpp b/src/kvstore/raftex/test/RaftexTestBase.cpp index 3234644ec1c..5b9589d39c8 100644 --- a/src/kvstore/raftex/test/RaftexTestBase.cpp +++ b/src/kvstore/raftex/test/RaftexTestBase.cpp @@ -198,7 +198,7 @@ void setupRaft(int32_t numCopies, copies.back()->start(getPeers(allHosts, allHosts[i], isLearner), isLearner[i]); } - // Wait untill all copies agree on the same leader + // Wait until all copies agree on the same leader waitUntilLeaderElected(copies, leader, isLearner); } @@ -282,7 +282,7 @@ bool checkConsensus(std::vector>& copies, std::vector& msgs) { int32_t count = 0; for (; count < 3; count++) { - bool concensus = true; + bool consensus = true; // Sleep a while to make sure the last log has been committed on followers sleep(FLAGS_raft_heartbeat_interval_secs); @@ -290,12 +290,12 @@ bool checkConsensus(std::vector>& copies, for (auto& c : copies) { if (c != nullptr && c->isRunning()) { if (msgs.size() != c->getNumLogs() || !checkLog(c, start, end, msgs)) { - concensus = false; + consensus = false; break; } } } - if (concensus == true) { + if (consensus == true) { return true; } } diff --git a/src/kvstore/raftex/test/SnapshotTest.cpp b/src/kvstore/raftex/test/SnapshotTest.cpp deleted file mode 100644 index 9ff5a6eb656..00000000000 --- a/src/kvstore/raftex/test/SnapshotTest.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (c) 2019 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include -#include - -#include "common/base/Base.h" -#include "common/fs/FileUtils.h" -#include "common/fs/TempDir.h" -#include "common/network/NetworkUtils.h" -#include "common/thread/GenericThreadPool.h" -#include "kvstore/raftex/RaftexService.h" -#include "kvstore/raftex/test/RaftexTestBase.h" -#include "kvstore/raftex/test/TestShard.h" - -DECLARE_uint32(raft_heartbeat_interval_secs); -DECLARE_int32(wal_ttl); -DECLARE_int64(wal_file_size); -DECLARE_int32(wal_buffer_size); -DECLARE_int32(wal_buffer_num); -DECLARE_int32(raft_rpc_timeout_ms); - -namespace nebula { -namespace raftex { - -TEST(SnapshotTest, LearnerCatchUpDataTest) { - fs::TempDir walRoot("/tmp/catch_up_data.XXXXXX"); - FLAGS_wal_file_size = 1024; - FLAGS_wal_buffer_size = 512; - FLAGS_raft_rpc_timeout_ms = 2000; - std::shared_ptr workers; - std::vector wals; - std::vector allHosts; - std::vector> services; - std::vector> copies; - - std::shared_ptr leader; - std::vector isLearner = {false, false, false, true}; - setupRaft(4, walRoot, workers, wals, allHosts, services, copies, leader, isLearner); - - // Check all hosts agree on the same leader - checkLeadership(copies, leader); - - std::vector msgs; - for (int i = 0; i < 10; i++) { - appendLogs(i * 100, i * 100 + 99, leader, msgs, true); - } - // Sleep a while to make sure the last log has been committed on followers - sleep(FLAGS_raft_heartbeat_interval_secs); - - // Check every copy - for (int i = 0; i < 3; i++) { - ASSERT_EQ(1000, copies[i]->getNumLogs()); - } - - for (int i = 0; i < 1000; ++i) { - for (int j = 0; j < 3; j++) { - folly::StringPiece msg; - ASSERT_TRUE(copies[j]->getLogMsg(i, msg)); - ASSERT_EQ(msgs[i], msg.toString()); - } - } - // wait for the wal to be cleaned - FLAGS_wal_ttl = 1; - sleep(FLAGS_wal_ttl + 3); - FLAGS_wal_ttl = 60; - LOG(INFO) << "Add learner, we need to catch up data!"; - auto f = leader->sendCommandAsync(test::encodeLearner(allHosts[3])); - f.wait(); - - LOG(INFO) << "Let's continue to write some logs"; - for (int i = 10; i < 20; i++) { - appendLogs(i * 100, i * 100 + 99, leader, msgs, true); - } - sleep(FLAGS_raft_heartbeat_interval_secs); - - auto& learner = copies[3]; - ASSERT_EQ(2000, learner->getNumLogs()); - for (int i = 0; i < 2000; ++i) { - folly::StringPiece msg; - ASSERT_TRUE(learner->getLogMsg(i, msg)); - ASSERT_EQ(msgs[i], msg.toString()); - } - - LOG(INFO) << "Finished UT"; - finishRaft(services, copies, workers, leader); -} - -} // namespace raftex -} // namespace nebula - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - folly::init(&argc, &argv, true); - google::SetStderrLogging(google::INFO); - - return RUN_ALL_TESTS(); -} diff --git a/src/kvstore/test/CMakeLists.txt b/src/kvstore/test/CMakeLists.txt index 7c872b29eda..a9a844f1786 100644 --- a/src/kvstore/test/CMakeLists.txt +++ b/src/kvstore/test/CMakeLists.txt @@ -5,6 +5,7 @@ set(KVSTORE_TEST_LIBS $ $ $ + $ $ $ $ diff --git a/src/kvstore/test/LogEncoderTest.cpp b/src/kvstore/test/LogEncoderTest.cpp index 02ee5753c86..f57e1a9d61e 100644 --- a/src/kvstore/test/LogEncoderTest.cpp +++ b/src/kvstore/test/LogEncoderTest.cpp @@ -134,17 +134,17 @@ TEST(LogEncoderTest, BatchTest) { auto encoded = encodeBatchValue(helper->getBatch()); auto decoded = decodeBatchValue(encoded.c_str()); - std::vector>> expectd; - expectd.emplace_back(OP_BATCH_REMOVE, - std::pair("remove", "")); - expectd.emplace_back(OP_BATCH_PUT, - std::pair("put_key", "put_value")); - expectd.emplace_back(OP_BATCH_REMOVE_RANGE, - std::pair("begin", "end")); - expectd.emplace_back( + std::vector>> expected; + expected.emplace_back(OP_BATCH_REMOVE, + std::pair("remove", "")); + expected.emplace_back(OP_BATCH_PUT, + std::pair("put_key", "put_value")); + expected.emplace_back(OP_BATCH_REMOVE_RANGE, + std::pair("begin", "end")); + expected.emplace_back( OP_BATCH_PUT, std::pair("put_key_again", "put_value_again")); - ASSERT_EQ(expectd, decoded); + ASSERT_EQ(expected, decoded); } } // namespace kvstore diff --git a/src/kvstore/test/NebulaListenerTest.cpp b/src/kvstore/test/NebulaListenerTest.cpp index 5d996625dd8..7cfe56cb4bd 100644 --- a/src/kvstore/test/NebulaListenerTest.cpp +++ b/src/kvstore/test/NebulaListenerTest.cpp @@ -227,7 +227,7 @@ class ListenerBasicTest : public ::testing::TestWithParamstart(std::move(raftPeers)); listeners_[index]->spaceListeners_[spaceId_]->listeners_[partId].emplace( meta::cpp2::ListenerType::UNKNOWN, dummy); - dummys_.emplace(partId, dummy); + dummies_.emplace(partId, dummy); } } @@ -287,9 +287,9 @@ class ListenerBasicTest : public ::testing::TestWithParam listenerHosts_; std::vector> stores_; std::vector> listeners_; - // dummys_ is a copy of Listener in listeners_, for convience to check + // dummies_ is a copy of Listener in listeners_, for convenience to check // consensus - std::unordered_map> dummys_; + std::unordered_map> dummies_; }; class ListenerAdvanceTest : public ListenerBasicTest { @@ -338,7 +338,7 @@ TEST_P(ListenerBasicTest, SimpleTest) { LOG(INFO) << "Check listener's data"; for (int32_t partId = 1; partId <= partCount_; partId++) { - auto dummy = dummys_[partId]; + auto dummy = dummies_[partId]; const auto& data = dummy->data(); CHECK_EQ(100, data.size()); for (int32_t i = 0; i < static_cast(data.size()); i++) { @@ -367,7 +367,7 @@ TEST_P(ListenerBasicTest, TransLeaderTest) { baton.wait(); } - LOG(INFO) << "Trasfer all part leader to first replica"; + LOG(INFO) << "Transfer all part leader to first replica"; auto targetAddr = NebulaStore::getRaftAddr(peers_[0]); for (int32_t partId = 1; partId <= partCount_; partId++) { folly::Baton baton; @@ -408,7 +408,7 @@ TEST_P(ListenerBasicTest, TransLeaderTest) { LOG(INFO) << "Check listener's data"; for (int32_t partId = 1; partId <= partCount_; partId++) { - auto dummy = dummys_[partId]; + auto dummy = dummies_[partId]; const auto& data = dummy->data(); CHECK_EQ(200, data.size()); for (int32_t i = 0; i < static_cast(data.size()); i++) { @@ -433,7 +433,7 @@ TEST_P(ListenerBasicTest, CommitSnapshotTest) { size += kvStr.size(); rows.emplace_back(kvStr); } - auto dummy = dummys_[partId]; + auto dummy = dummies_[partId]; auto ret = dummy->commitSnapshot(rows, 100, 1, true); CHECK_EQ(ret.first, 100); CHECK_EQ(ret.second, size); @@ -441,7 +441,7 @@ TEST_P(ListenerBasicTest, CommitSnapshotTest) { LOG(INFO) << "Check listener's data"; for (int32_t partId = 1; partId <= partCount_; partId++) { - auto dummy = dummys_[partId]; + auto dummy = dummies_[partId]; const auto& data = dummy->data(); CHECK_EQ(100, data.size()); for (int32_t i = 0; i < static_cast(data.size()); i++) { @@ -477,29 +477,29 @@ TEST_P(ListenerBasicTest, ListenerResetByWalTest) { sleep(FLAGS_raft_heartbeat_interval_secs + 3); for (int32_t partId = 1; partId <= partCount_; partId++) { - auto dummy = dummys_[partId]; + auto dummy = dummies_[partId]; const auto& data = dummy->data(); CHECK_EQ(100000, data.size()); } for (int32_t partId = 1; partId <= partCount_; partId++) { - dummys_[partId]->resetListener(); - CHECK_EQ(0, dummys_[partId]->data().size()); - CHECK_EQ(0, dummys_[partId]->getApplyId()); + dummies_[partId]->resetListener(); + CHECK_EQ(0, dummies_[partId]->data().size()); + CHECK_EQ(0, dummies_[partId]->getApplyId()); } sleep(FLAGS_raft_heartbeat_interval_secs + 3); for (int32_t partId = 1; partId <= partCount_; partId++) { while (true) { - if (dummys_[partId]->pursueLeaderDone()) { + if (dummies_[partId]->pursueLeaderDone()) { break; } } } for (int32_t partId = 1; partId <= partCount_; partId++) { - auto dummy = dummys_[partId]; + auto dummy = dummies_[partId]; const auto& data = dummy->data(); CHECK_EQ(100000, data.size()); } @@ -510,7 +510,7 @@ TEST_P(ListenerAdvanceTest, ListenerResetBySnapshotTest) { for (int32_t i = 0; i < 10; i++) { std::vector data; for (int32_t j = 0; j < 1000; j++) { - auto vKey = NebulaKeyUtils::vertexKey(8, partId, folly::to(i * 1000 + j), 5); + auto vKey = NebulaKeyUtils::tagKey(8, partId, folly::to(i * 1000 + j), 5); data.emplace_back(std::move(vKey), folly::stringPrintf("val_%d_%d", partId, i * 1000 + j)); } auto leader = findLeader(partId); @@ -529,7 +529,7 @@ TEST_P(ListenerAdvanceTest, ListenerResetBySnapshotTest) { sleep(2 * FLAGS_raft_heartbeat_interval_secs); for (int32_t partId = 1; partId <= partCount_; partId++) { - auto dummy = dummys_[partId]; + auto dummy = dummies_[partId]; const auto& data = dummy->data(); CHECK_EQ(10000, data.size()); } @@ -550,9 +550,9 @@ TEST_P(ListenerAdvanceTest, ListenerResetBySnapshotTest) { } for (int32_t partId = 1; partId <= partCount_; partId++) { - dummys_[partId]->resetListener(); - CHECK_EQ(0, dummys_[partId]->getApplyId()); - auto termAndId = dummys_[partId]->committedId(); + dummies_[partId]->resetListener(); + CHECK_EQ(0, dummies_[partId]->getApplyId()); + auto termAndId = dummies_[partId]->committedId(); CHECK_EQ(0, termAndId.first); CHECK_EQ(0, termAndId.second); } @@ -563,10 +563,10 @@ TEST_P(ListenerAdvanceTest, ListenerResetBySnapshotTest) { for (int32_t partId = 1; partId <= partCount_; partId++) { auto retry = 0; while (retry++ < 6) { - auto result = dummys_[partId]->committedSnapshot(); + auto result = dummies_[partId]->committedSnapshot(); if (result.first >= 10000) { partResult.emplace_back(true); - ASSERT_EQ(10000, dummys_[partId]->data().size()); + ASSERT_EQ(10000, dummies_[partId]->data().size()); break; } usleep(1000); @@ -579,12 +579,13 @@ TEST_P(ListenerAdvanceTest, ListenerResetBySnapshotTest) { TEST_P(ListenerSnapshotTest, SnapshotRateLimitTest) { for (int32_t partId = 1; partId <= partCount_; partId++) { // Write 10000 kvs in a part, key size is sizeof(partId) + vId + tagId = 4 + 8 + 4 = 16, - // value size is 24, so total size of a kv is 40. The snapshot size of a parition will be around - // 400Kb, and the rate limit is set to 40Kb, so snapshot will be sent at least 10 seconds. + // value size is 24, so total size of a kv is 40. The snapshot size of a partition will be + // around 400Kb, and the rate limit is set to 40Kb, so snapshot will be sent at least 10 + // seconds. for (int32_t i = 0; i < 10; i++) { std::vector data; for (int32_t j = 0; j < 1000; j++) { - auto vKey = NebulaKeyUtils::vertexKey(8, partId, folly::to(i * 1000 + j), 5); + auto vKey = NebulaKeyUtils::tagKey(8, partId, folly::to(i * 1000 + j), 5); data.emplace_back(std::move(vKey), std::string(24, 'X')); } auto leader = findLeader(partId); @@ -603,7 +604,7 @@ TEST_P(ListenerSnapshotTest, SnapshotRateLimitTest) { sleep(2 * FLAGS_raft_heartbeat_interval_secs); for (int32_t partId = 1; partId <= partCount_; partId++) { - auto dummy = dummys_[partId]; + auto dummy = dummies_[partId]; const auto& data = dummy->data(); CHECK_EQ(10000, data.size()); } @@ -624,27 +625,27 @@ TEST_P(ListenerSnapshotTest, SnapshotRateLimitTest) { } for (int32_t partId = 1; partId <= partCount_; partId++) { - dummys_[partId]->resetListener(); - CHECK_EQ(0, dummys_[partId]->getApplyId()); - auto termAndId = dummys_[partId]->committedId(); + dummies_[partId]->resetListener(); + CHECK_EQ(0, dummies_[partId]->getApplyId()); + auto termAndId = dummies_[partId]->committedId(); CHECK_EQ(0, termAndId.first); CHECK_EQ(0, termAndId.second); } // listener will try to pull snapshot for now. Since we have limit the snapshot send rate to 40Kb // in 1 second and batch size will be 10Kb, it would take at least 10 second to finish. Besides, - // there be at least 40 batchs + // there be at least 40 batches auto startTime = time::WallClock::fastNowInSec(); while (true) { std::vector partResult; for (int32_t partId = 1; partId <= partCount_; partId++) { - auto result = dummys_[partId]->committedSnapshot(); + auto result = dummies_[partId]->committedSnapshot(); if (result.first >= 10000) { partResult.emplace_back(true); - ASSERT_EQ(10000, dummys_[partId]->data().size()); + ASSERT_EQ(10000, dummies_[partId]->data().size()); ASSERT_GE(time::WallClock::fastNowInSec() - startTime, 10); - ASSERT_GE(dummys_[partId]->snapshotBatchCount(), 40); + ASSERT_GE(dummies_[partId]->snapshotBatchCount(), 40); } } if (static_cast(partResult.size()) == partCount_) { diff --git a/src/kvstore/test/NebulaStoreTest.cpp b/src/kvstore/test/NebulaStoreTest.cpp index 5eae7d68b19..f189b66449e 100644 --- a/src/kvstore/test/NebulaStoreTest.cpp +++ b/src/kvstore/test/NebulaStoreTest.cpp @@ -436,7 +436,7 @@ TEST(NebulaStoreTest, TransLeaderTest) { }; LOG(INFO) << "Transfer leader to first copy"; - // all parttition tranfer leaders to first replica + // all partition transfer leaders to first replica GraphSpaceID spaceId = 0; for (int i = 0; i < 3; i++) { PartitionID partId = i; @@ -950,7 +950,7 @@ TEST(NebulaStoreTest, BackupRestoreTest) { if (insertData) { std::vector data; for (auto tagId = 0; tagId < 10; tagId++) { - data.emplace_back(NebulaKeyUtils::vertexKey(vIdLen, partId, "vertex", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(vIdLen, partId, "vertex", tagId), folly::stringPrintf("val_%d", tagId)); } folly::Baton baton; @@ -962,7 +962,7 @@ TEST(NebulaStoreTest, BackupRestoreTest) { } { - std::string prefix = NebulaKeyUtils::vertexPrefix(vIdLen, partId, "vertex"); + std::string prefix = NebulaKeyUtils::tagPrefix(vIdLen, partId, "vertex"); std::unique_ptr iter; auto code = store->prefix(spaceId, partId, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); diff --git a/src/kvstore/test/PartTest.cpp b/src/kvstore/test/PartTest.cpp index 53ea164b16d..900f7bc8357 100644 --- a/src/kvstore/test/PartTest.cpp +++ b/src/kvstore/test/PartTest.cpp @@ -23,7 +23,7 @@ void checkVertexData(RocksEngine* engine, PartitionID partId, int expectNum, bool checkVal = false) { - std::string vertexPrefix = NebulaKeyUtils::vertexPrefix(partId); + std::string vertexPrefix = NebulaKeyUtils::tagPrefix(partId); std::unique_ptr iter; auto code = engine->prefix(vertexPrefix, &iter); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -105,16 +105,16 @@ TEST(PartTest, KeyOrderTest) { // build vertex data in part 1, 2 while (partId < 3) { - auto key1 = NebulaKeyUtils::vertexKey(kDefaultVIdLen, partId, "", 0); + auto key1 = NebulaKeyUtils::tagKey(kDefaultVIdLen, partId, "", 0); data.emplace_back(key1, folly::stringPrintf("val%d", 1)); - auto key2 = NebulaKeyUtils::vertexKey(kDefaultVIdLen, partId, "", INT_MAX); + auto key2 = NebulaKeyUtils::tagKey(kDefaultVIdLen, partId, "", INT_MAX); data.emplace_back(key2, folly::stringPrintf("val%d", 2)); - auto key3 = NebulaKeyUtils::vertexKey(kDefaultVIdLen, partId, "ffffff", INT_MAX, '\377'); + auto key3 = NebulaKeyUtils::tagKey(kDefaultVIdLen, partId, "ffffff", INT_MAX, '\377'); data.emplace_back(key3, folly::stringPrintf("val%d", 3)); - auto key4 = NebulaKeyUtils::vertexKey(kDefaultVIdLen, partId, "", INT_MAX, '\377'); + auto key4 = NebulaKeyUtils::tagKey(kDefaultVIdLen, partId, "", INT_MAX, '\377'); data.emplace_back(key4, folly::stringPrintf("val%d", 4)); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, engine->multiPut(data)); @@ -141,12 +141,12 @@ TEST(PartTest, PartCleanTest) { while (partId < 3) { TagID tagId = 1; for (int i = 0; i < 10; i++) { - auto key = NebulaKeyUtils::vertexKey(kDefaultVIdLen, partId, std::to_string(i), tagId); + auto key = NebulaKeyUtils::tagKey(kDefaultVIdLen, partId, std::to_string(i), tagId); data.emplace_back(key, folly::stringPrintf("val%d", i)); } tagId = 2; for (int i = 0; i < 10; i++) { - auto key = NebulaKeyUtils::vertexKey(kDefaultVIdLen, partId, std::to_string(i), tagId); + auto key = NebulaKeyUtils::tagKey(kDefaultVIdLen, partId, std::to_string(i), tagId); data.emplace_back(key, folly::stringPrintf("val%d", i)); } @@ -196,7 +196,7 @@ TEST(PartTest, PartCleanTest) { // remove range part::clean data partId = 1; - const auto& vertexPre = NebulaKeyUtils::vertexPrefix(partId); + const auto& vertexPre = NebulaKeyUtils::tagPrefix(partId); auto ret = engine->removeRange(NebulaKeyUtils::firstKey(vertexPre, kDefaultVIdLen), NebulaKeyUtils::lastKey(vertexPre, kDefaultVIdLen)); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); diff --git a/src/kvstore/test/RateLimiterTest.cpp b/src/kvstore/test/RateLimiterTest.cpp index 2c99d844462..6961a4cf1bb 100644 --- a/src/kvstore/test/RateLimiterTest.cpp +++ b/src/kvstore/test/RateLimiterTest.cpp @@ -15,7 +15,7 @@ DECLARE_uint32(snapshot_part_rate_limit); namespace nebula { namespace kvstore { -TEST(RateLimter, ConsumeLessEqualThanBurst) { +TEST(RateLimiter, ConsumeLessEqualThanBurst) { RateLimiter limiter; auto now = time::WallClock::fastNowInSec(); int64_t count = 0; @@ -27,7 +27,7 @@ TEST(RateLimter, ConsumeLessEqualThanBurst) { EXPECT_GE(time::WallClock::fastNowInSec() - now, 5); } -TEST(RateLimter, ConsumeGreaterThanBurst) { +TEST(RateLimiter, ConsumeGreaterThanBurst) { RateLimiter limiter; auto now = time::WallClock::fastNowInSec(); int64_t count = 0; @@ -40,7 +40,7 @@ TEST(RateLimter, ConsumeGreaterThanBurst) { EXPECT_GE(time::WallClock::fastNowInSec() - now, 5); } -TEST(RateLimter, RateLessThanBurst) { +TEST(RateLimiter, RateLessThanBurst) { RateLimiter limiter; auto now = time::WallClock::fastNowInSec(); int64_t count = 0; diff --git a/src/kvstore/test/RocksEngineTest.cpp b/src/kvstore/test/RocksEngineTest.cpp index 9d325102bf4..a12885bbdb2 100644 --- a/src/kvstore/test/RocksEngineTest.cpp +++ b/src/kvstore/test/RocksEngineTest.cpp @@ -206,13 +206,13 @@ TEST_P(RocksEngineTest, IngestTest) { rocksdb::SstFileWriter writer(rocksdb::EnvOptions(), options); fs::TempDir rootPath("/tmp/rocksdb_engine_IngestTest.XXXXXX"); auto file = folly::stringPrintf("%s/%s", rootPath.path(), "data.sst"); - auto stauts = writer.Open(file); - ASSERT_TRUE(stauts.ok()); + auto status = writer.Open(file); + ASSERT_TRUE(status.ok()); - stauts = writer.Put("key", "value"); - ASSERT_TRUE(stauts.ok()); - stauts = writer.Put("key_empty", ""); - ASSERT_TRUE(stauts.ok()); + status = writer.Put("key", "value"); + ASSERT_TRUE(status.ok()); + status = writer.Put("key_empty", ""); + ASSERT_TRUE(status.ok()); writer.Finish(); auto engine = std::make_unique(0, kDefaultVIdLen, rootPath.path()); @@ -300,17 +300,17 @@ TEST_P(RocksEngineTest, VertexWholeKeyBloomFilterTest) { auto engine = std::make_unique(0, kDefaultVIdLen, rootPath.path()); PartitionID partId = 1; VertexID vId = "vertex"; - VertexID notExisted = "notexist"; + VertexID nonexistent = "notExist"; auto writeVertex = [&](TagID tagId) { std::vector data; - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, partId, vId, tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, partId, vId, tagId), folly::stringPrintf("val_%d", tagId)); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, engine->multiPut(std::move(data))); }; auto readVertex = [&](TagID tagId) { - auto key = NebulaKeyUtils::vertexKey(kDefaultVIdLen, partId, vId, tagId); + auto key = NebulaKeyUtils::tagKey(kDefaultVIdLen, partId, vId, tagId); std::string val; auto ret = engine->get(key, &val); if (ret == nebula::cpp2::ErrorCode::SUCCEEDED) { @@ -321,7 +321,7 @@ TEST_P(RocksEngineTest, VertexWholeKeyBloomFilterTest) { }; auto scanVertex = [&](VertexID id) { - auto prefix = NebulaKeyUtils::vertexPrefix(kDefaultVIdLen, partId, id); + auto prefix = NebulaKeyUtils::tagPrefix(kDefaultVIdLen, partId, id); std::unique_ptr iter; auto ret = engine->prefix(prefix, &iter); EXPECT_EQ(ret, nebula::cpp2::ErrorCode::SUCCEEDED); @@ -344,7 +344,7 @@ TEST_P(RocksEngineTest, VertexWholeKeyBloomFilterTest) { if (FLAGS_enable_rocksdb_prefix_filtering) { scanVertex(vId); EXPECT_EQ(statistics->getTickerCount(rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL), 0); - scanVertex(notExisted); + scanVertex(nonexistent); EXPECT_EQ(statistics->getTickerCount(rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL), 0); } @@ -361,7 +361,7 @@ TEST_P(RocksEngineTest, VertexWholeKeyBloomFilterTest) { scanVertex(vId); EXPECT_EQ(statistics->getTickerCount(rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL), 0); // read not exists data, prefix key bloom filter will be useful - scanVertex(notExisted); + scanVertex(nonexistent); EXPECT_GT(statistics->getTickerCount(rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL), 0); } @@ -377,7 +377,7 @@ TEST_P(RocksEngineTest, EdgeWholeKeyBloomFilterTest) { auto engine = std::make_unique(0, kDefaultVIdLen, rootPath.path()); PartitionID partId = 1; VertexID vId = "vertex"; - VertexID notExisted = "notexist"; + VertexID nonexistent = "notExist"; auto writeEdge = [&](EdgeType edgeType) { std::vector data; @@ -421,7 +421,7 @@ TEST_P(RocksEngineTest, EdgeWholeKeyBloomFilterTest) { if (FLAGS_enable_rocksdb_prefix_filtering) { scanEdge(vId); EXPECT_EQ(statistics->getTickerCount(rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL), 0); - scanEdge(notExisted); + scanEdge(nonexistent); EXPECT_EQ(statistics->getTickerCount(rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL), 0); } @@ -438,7 +438,7 @@ TEST_P(RocksEngineTest, EdgeWholeKeyBloomFilterTest) { scanEdge(vId); EXPECT_EQ(statistics->getTickerCount(rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL), 0); // read not exists data, prefix key bloom filter will be useful - scanEdge(notExisted); + scanEdge(nonexistent); EXPECT_GT(statistics->getTickerCount(rocksdb::Tickers::BLOOM_FILTER_PREFIX_USEFUL), 0); } @@ -451,13 +451,13 @@ TEST_P(RocksEngineTest, PrefixBloomTest) { std::vector data; for (auto tagId = 0; tagId < 10; tagId++) { - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 1, "1", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, 1, "1", tagId), folly::stringPrintf("val_%d", tagId)); - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 1, "2", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, 1, "2", tagId), folly::stringPrintf("val_%d", tagId)); - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 2, "3", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, 2, "3", tagId), folly::stringPrintf("val_%d", tagId)); - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 2, "4", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, 2, "4", tagId), folly::stringPrintf("val_%d", tagId)); } data.emplace_back(NebulaKeyUtils::systemCommitKey(1), "123"); @@ -467,7 +467,7 @@ TEST_P(RocksEngineTest, PrefixBloomTest) { { // vertexPrefix(partId) will not be included auto checkVertexPrefix = [&](PartitionID partId, const VertexID& vId) { - std::string prefix = NebulaKeyUtils::vertexPrefix(kDefaultVIdLen, partId, vId); + std::string prefix = NebulaKeyUtils::tagPrefix(kDefaultVIdLen, partId, vId); std::unique_ptr iter; auto code = engine->prefix(prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -486,7 +486,7 @@ TEST_P(RocksEngineTest, PrefixBloomTest) { { // vertexPrefix(partId) will be included auto checkPartPrefix = [&](PartitionID partId) { - std::string prefix = NebulaKeyUtils::vertexPrefix(partId); + std::string prefix = NebulaKeyUtils::tagPrefix(partId); std::unique_ptr iter; auto code = engine->prefix(prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -503,7 +503,7 @@ TEST_P(RocksEngineTest, PrefixBloomTest) { { // vertexPrefix(partId) will be included auto checkRangeWithPartPrefix = [&](PartitionID partId) { - std::string prefix = NebulaKeyUtils::vertexPrefix(partId); + std::string prefix = NebulaKeyUtils::tagPrefix(partId); std::unique_ptr iter; auto code = engine->rangeWithPrefix(prefix, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -578,7 +578,7 @@ TEST(PlainTableTest, BackupRestoreWithData) { PartitionID partId = 1; auto checkData = [&] { - std::string prefix = NebulaKeyUtils::vertexPrefix(kDefaultVIdLen, partId, "vertex"); + std::string prefix = NebulaKeyUtils::tagPrefix(kDefaultVIdLen, partId, "vertex"); std::unique_ptr iter; auto code = engine->prefix(prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -598,7 +598,7 @@ TEST(PlainTableTest, BackupRestoreWithData) { LOG(INFO) << "Write some data"; std::vector data; for (auto tagId = 0; tagId < 10; tagId++) { - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, partId, "vertex", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, partId, "vertex", tagId), folly::stringPrintf("val_%d", tagId)); } data.emplace_back(NebulaKeyUtils::systemCommitKey(partId), "123"); @@ -635,7 +635,7 @@ TEST(RebuildPrefixBloomFilter, RebuildPrefixBloomFilter) { auto checkData = [&] { auto checkVertexPrefix = [&](PartitionID partId, VertexID vId) { { - std::string prefix = NebulaKeyUtils::vertexPrefix(kDefaultVIdLen, partId, vId); + std::string prefix = NebulaKeyUtils::tagPrefix(kDefaultVIdLen, partId, vId); std::unique_ptr iter; auto code = engine->prefix(prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -647,7 +647,7 @@ TEST(RebuildPrefixBloomFilter, RebuildPrefixBloomFilter) { EXPECT_EQ(num, 10); } for (TagID tagId = 0; tagId < 10; tagId++) { - std::string prefix = NebulaKeyUtils::vertexPrefix(kDefaultVIdLen, partId, vId, tagId); + std::string prefix = NebulaKeyUtils::tagPrefix(kDefaultVIdLen, partId, vId, tagId); std::unique_ptr iter; auto code = engine->prefix(prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -688,7 +688,7 @@ TEST(RebuildPrefixBloomFilter, RebuildPrefixBloomFilter) { }; auto checkVertexPartPrefix = [&](PartitionID partId) { - std::string prefix = NebulaKeyUtils::vertexPrefix(partId); + std::string prefix = NebulaKeyUtils::tagPrefix(partId); std::unique_ptr iter; auto code = engine->prefix(prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -714,7 +714,7 @@ TEST(RebuildPrefixBloomFilter, RebuildPrefixBloomFilter) { }; auto checkRangeWithPartPrefix = [&](PartitionID partId) { - std::string prefix = NebulaKeyUtils::vertexPrefix(partId); + std::string prefix = NebulaKeyUtils::tagPrefix(partId); std::unique_ptr iter; auto code = engine->rangeWithPrefix(prefix, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -762,13 +762,13 @@ TEST(RebuildPrefixBloomFilter, RebuildPrefixBloomFilter) { LOG(INFO) << "Write some data"; std::vector data; for (TagID tagId = 0; tagId < 10; tagId++) { - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 1, "1", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, 1, "1", tagId), folly::stringPrintf("val_%d", tagId)); - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 1, "2", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, 1, "2", tagId), folly::stringPrintf("val_%d", tagId)); - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 2, "3", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, 2, "3", tagId), folly::stringPrintf("val_%d", tagId)); - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 2, "4", tagId), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, 2, "4", tagId), folly::stringPrintf("val_%d", tagId)); } EdgeRanking rank = 0; @@ -790,7 +790,7 @@ TEST(RebuildPrefixBloomFilter, RebuildPrefixBloomFilter) { auto writeNewData = [&engine] { std::vector data; - data.emplace_back(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 3, "5", 0), + data.emplace_back(NebulaKeyUtils::tagKey(kDefaultVIdLen, 3, "5", 0), "vertex_data_after_enable_prefix_bloom_filter"); data.emplace_back(NebulaKeyUtils::edgeKey(kDefaultVIdLen, 3, "5", 0, 0, "5"), "edge_data_after_enable_prefix_bloom_filter"); @@ -800,7 +800,7 @@ TEST(RebuildPrefixBloomFilter, RebuildPrefixBloomFilter) { auto checkNewData = [&engine] { std::string value; - auto code = engine->get(NebulaKeyUtils::vertexKey(kDefaultVIdLen, 3, "5", 0), &value); + auto code = engine->get(NebulaKeyUtils::tagKey(kDefaultVIdLen, 3, "5", 0), &value); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); EXPECT_EQ("vertex_data_after_enable_prefix_bloom_filter", value); code = engine->get(NebulaKeyUtils::edgeKey(kDefaultVIdLen, 3, "5", 0, 0, "5"), &value); @@ -818,9 +818,9 @@ TEST(RebuildPrefixBloomFilter, RebuildPrefixBloomFilter) { EXPECT_EQ(num, 1); }; - checkPrefix(NebulaKeyUtils::vertexPrefix(3)); - checkPrefix(NebulaKeyUtils::vertexPrefix(kDefaultVIdLen, 3, "5")); - checkPrefix(NebulaKeyUtils::vertexPrefix(kDefaultVIdLen, 3, "5", 0)); + checkPrefix(NebulaKeyUtils::tagPrefix(3)); + checkPrefix(NebulaKeyUtils::tagPrefix(kDefaultVIdLen, 3, "5")); + checkPrefix(NebulaKeyUtils::tagPrefix(kDefaultVIdLen, 3, "5", 0)); checkPrefix(NebulaKeyUtils::edgePrefix(3)); checkPrefix(NebulaKeyUtils::edgePrefix(kDefaultVIdLen, 3, "5")); checkPrefix(NebulaKeyUtils::edgePrefix(kDefaultVIdLen, 3, "5", 0)); diff --git a/src/kvstore/wal/AtomicLogBuffer.h b/src/kvstore/wal/AtomicLogBuffer.h index b6023266e21..46477cf2c49 100644 --- a/src/kvstore/wal/AtomicLogBuffer.h +++ b/src/kvstore/wal/AtomicLogBuffer.h @@ -230,7 +230,7 @@ class AtomicLogBuffer : public std::enable_shared_from_this { if (size_ + recSize > capacity_) { auto* tail = tail_.load(std::memory_order_relaxed); // todo(doodle): there is a potential problem is that: since Node::isFull - // is judeged by log count, we can only add new node when previous node + // is judged by log count, we can only add new node when previous node // has enough logs. So when tail is equal to head, we need to wait tail is // full, after head moves forward, at then tail can be marked as deleted. // So the log buffer would takes up more memory than its capacity. Since diff --git a/src/kvstore/wal/FileBasedWal.cpp b/src/kvstore/wal/FileBasedWal.cpp index ac6af23f6dc..e55f3e72bbc 100644 --- a/src/kvstore/wal/FileBasedWal.cpp +++ b/src/kvstore/wal/FileBasedWal.cpp @@ -226,7 +226,7 @@ void FileBasedWal::scanAllWalFiles() { if (!walFiles_.empty()) { auto it = walFiles_.rbegin(); - // Try to scan last wal, if it is invalid or empty, scan the privous one + // Try to scan last wal, if it is invalid or empty, scan the previous one scanLastWal(it->second, it->second->firstId()); if (it->second->lastId() <= 0) { unlink(it->second->path()); @@ -353,7 +353,6 @@ void FileBasedWal::rollbackInFile(WalFileInfoPtr info, LogID logId) { } lastLogId_ = logId; lastLogTerm_ = term; - LOG(INFO) << idStr_ << "Rollback to log " << logId; CHECK_GT(pos, 0) << "This wal should have been deleted"; if (pos < FileUtils::fileSize(path)) { @@ -414,7 +413,7 @@ void FileBasedWal::scanLastWal(WalFileInfoPtr info, LogID firstId) { } if (head != foot) { - LOG(ERROR) << "Message size doen't match: " << head << " != " << foot; + LOG(ERROR) << "Message size doesn't match: " << head << " != " << foot; break; } @@ -610,6 +609,8 @@ bool FileBasedWal::rollbackToLog(LogID id) { VLOG(1) << "Roll back to log " << id << ", the last WAL file is now \"" << walFiles_.rbegin()->second->path() << "\""; rollbackInFile(walFiles_.rbegin()->second, id); + CHECK_EQ(lastLogId_, id); + CHECK_EQ(walFiles_.rbegin()->second->lastId(), id); } } @@ -631,7 +632,7 @@ bool FileBasedWal::reset() { std::vector files = FileUtils::listAllFilesInDir(dir_.c_str(), false, "*.wal"); for (auto& fn : files) { auto absFn = FileUtils::joinPath(dir_, fn); - LOG(INFO) << "Removing " << absFn; + VLOG(1) << "Removing " << absFn; unlink(absFn.c_str()); } lastLogId_ = firstLogId_ = 0; @@ -644,7 +645,7 @@ void FileBasedWal::cleanWAL() { return; } auto now = time::WallClock::fastNowInSec(); - // In theory we only need to keep the latest wal file because it is beging + // In theory we only need to keep the latest wal file because it is being // written now. However, sometimes will trigger raft snapshot even only a // small amount of logs is missing, especially when we reboot all storage, so // se keep one more wal. @@ -714,5 +715,14 @@ size_t FileBasedWal::accessAllWalInfo(std::function f return count; } +TermID FileBasedWal::getLogTerm(LogID id) { + TermID term = -1; + auto iter = iterator(id, id); + if (iter->valid()) { + term = iter->logTerm(); + } + return term; +} + } // namespace wal } // namespace nebula diff --git a/src/kvstore/wal/FileBasedWal.h b/src/kvstore/wal/FileBasedWal.h index f10cb52d989..57d9439a5d3 100644 --- a/src/kvstore/wal/FileBasedWal.h +++ b/src/kvstore/wal/FileBasedWal.h @@ -72,6 +72,9 @@ class FileBasedWal final : public Wal, public std::enable_shared_from_this wal, LogID startI } if (startId < wal_->firstLogId()) { - LOG(ERROR) << wal_->idStr_ << "The given log id " << startId - << " is out of the range, the wal firstLogId is " << wal_->firstLogId(); + VLOG(1) << wal_->idStr_ << "The given log id " << startId + << " is out of the range, the wal firstLogId is " << wal_->firstLogId(); currId_ = lastId_ + 1; return; } diff --git a/src/kvstore/wal/test/FileBasedWalTest.cpp b/src/kvstore/wal/test/FileBasedWalTest.cpp index 55b4004561c..a2a6a8a45f5 100644 --- a/src/kvstore/wal/test/FileBasedWalTest.cpp +++ b/src/kvstore/wal/test/FileBasedWalTest.cpp @@ -568,6 +568,40 @@ TEST(FileBasedWal, CleanWalBeforeIdTest) { CHECK_EQ(1000, wal->lastLogId()); } +TEST(FileBasedWal, getLogTermTest) { + TempDir walDir("/tmp/testWal.XXXXXX"); + FileBasedWalInfo info; + FileBasedWalPolicy policy; + policy.fileSize = 1024L * 1024L; + policy.bufferSize = 1024L * 1024L; + + auto wal = FileBasedWal::getWal( + walDir.path(), info, policy, [](LogID, TermID, ClusterID, const std::string&) { + return true; + }); + + // Append > 10MB logs in total + for (int i = 1; i <= 10000; i++) { + ASSERT_TRUE( + wal->appendLog(i /*id*/, i /*term*/, 0 /*cluster*/, folly::stringPrintf(kLongMsg, i))); + } + + // in the memory buffer + ASSERT_EQ(10000, wal->getLogTerm(10000)); + // in the file + ASSERT_EQ(4, wal->getLogTerm(4)); + + // Close the wal + wal.reset(); + + // Now let's open it to read + wal = FileBasedWal::getWal( + walDir.path(), info, policy, [](LogID, TermID, ClusterID, const std::string&) { + return true; + }); + EXPECT_EQ(10, wal->getLogTerm(10)); +} + } // namespace wal } // namespace nebula diff --git a/src/kvstore/wal/test/InMemoryLogBufferList.h b/src/kvstore/wal/test/InMemoryLogBufferList.h index 9fbd5aca0cd..12c2359e137 100644 --- a/src/kvstore/wal/test/InMemoryLogBufferList.h +++ b/src/kvstore/wal/test/InMemoryLogBufferList.h @@ -34,7 +34,7 @@ class InMemoryBufferList : public std::enable_shared_from_thisfirstLogId(); } if (firstIdInBuffer_ <= currId_) { - // Go no futher + // Go no further currIdx_ = currId_ - firstIdInBuffer_; nextFirstId_ = getFirstIdInNextBuffer(); return false; diff --git a/src/kvstore/wal/test/LogBufferBenchmark.cpp b/src/kvstore/wal/test/LogBufferBenchmark.cpp index 83cb7a5c27e..b1a6c9bbe7d 100644 --- a/src/kvstore/wal/test/LogBufferBenchmark.cpp +++ b/src/kvstore/wal/test/LogBufferBenchmark.cpp @@ -33,7 +33,7 @@ void prepareData(std::shared_ptr logBuffer, int32_t len, size_t } /************************* - * Begining of benchmarks + * Beginning of benchmarks ************************/ void runInMemoryLogBufferWriteTest(size_t iters, int32_t len) { @@ -379,7 +379,7 @@ int main(int argc, char** argv) { } /* Intel(R) Xeon(R) CPU E5-2690 v2 @ 3.00GHz --O2 kMaxLenght=64 write test +-O2 kMaxLength=64 write test ============================================================================ LogBufferBenchmark.cpprelative time/iter iters/s ============================================================================ diff --git a/src/meta/CMakeLists.txt b/src/meta/CMakeLists.txt index e3165b35fdf..f5ecbe7bcd8 100644 --- a/src/meta/CMakeLists.txt +++ b/src/meta/CMakeLists.txt @@ -47,8 +47,8 @@ nebula_add_library( processors/admin/CreateSnapshotProcessor.cpp processors/admin/DropSnapshotProcessor.cpp processors/admin/ListSnapshotsProcessor.cpp - processors/job/BalancePlan.cpp - processors/job/BalanceTask.cpp + processors/job/BalancePlan.cpp + processors/job/BalanceTask.cpp processors/admin/AdminClient.cpp processors/admin/SnapShot.cpp processors/admin/CreateBackupProcessor.cpp @@ -129,6 +129,7 @@ set(meta_test_deps $ $ $ + $ $ $ $ diff --git a/src/meta/KVBasedClusterIdMan.h b/src/meta/KVBasedClusterIdMan.h index 60f5be8f9ec..b791d2ae971 100644 --- a/src/meta/KVBasedClusterIdMan.h +++ b/src/meta/KVBasedClusterIdMan.h @@ -51,7 +51,7 @@ class ClusterIdMan { ::close(fd); return false; } - LOG(INFO) << "Persiste clusterId " << clusterId << " succeeded!"; + LOG(INFO) << "Persist clusterId " << clusterId << " succeeded!"; ::close(fd); return true; } diff --git a/src/meta/MetaServiceUtils.cpp b/src/meta/MetaServiceUtils.cpp index 113790af208..96a5bb857a9 100644 --- a/src/meta/MetaServiceUtils.cpp +++ b/src/meta/MetaServiceUtils.cpp @@ -234,7 +234,7 @@ ErrorOr> MetaServiceUtils::bac if (result != nebula::cpp2::ErrorCode::SUCCEEDED) { return result; } - LOG(INFO) << table.first << " table backup successed"; + LOG(INFO) << table.first << " table backup succeeded"; } if (spaceNames == nullptr) { @@ -248,7 +248,7 @@ ErrorOr> MetaServiceUtils::bac if (result != nebula::cpp2::ErrorCode::SUCCEEDED) { return result; } - LOG(INFO) << table.first << " table backup successed"; + LOG(INFO) << table.first << " table backup succeeded"; } } @@ -262,7 +262,7 @@ ErrorOr> MetaServiceUtils::bac if (result != nebula::cpp2::ErrorCode::SUCCEEDED) { return result; } - LOG(INFO) << table.first << " table backup successed"; + LOG(INFO) << table.first << " table backup succeeded"; } // The mapping of space name and space id needs to be handled separately. diff --git a/src/meta/processors/BaseProcessor-inl.h b/src/meta/processors/BaseProcessor-inl.h index b46862753c3..5b09579bd73 100644 --- a/src/meta/processors/BaseProcessor-inl.h +++ b/src/meta/processors/BaseProcessor-inl.h @@ -170,7 +170,7 @@ ErrorOr BaseProcessor::autoIncrementId() } template -ErrorOr BaseProcessor::getAvailableGolbalId() { +ErrorOr BaseProcessor::getAvailableGlobalId() { // A read lock has been added before call static const std::string kIdKey = "__id__"; int32_t id; @@ -206,7 +206,7 @@ ErrorOr BaseProcessor::autoIncrementIdIn // In order to be compatible with the existing old schema, and simple to implement, // when the local_id record does not exist in space, directly use the smallest // id available globally. - auto globalIdRet = getAvailableGolbalId(); + auto globalIdRet = getAvailableGlobalId(); if (!nebula::ok(globalIdRet)) { return nebula::error(globalIdRet); } diff --git a/src/meta/processors/BaseProcessor.h b/src/meta/processors/BaseProcessor.h index 37e8fbab200..537a583d448 100644 --- a/src/meta/processors/BaseProcessor.h +++ b/src/meta/processors/BaseProcessor.h @@ -162,7 +162,7 @@ class BaseProcessor { /** * Get the current available global id **/ - ErrorOr getAvailableGolbalId(); + ErrorOr getAvailableGlobalId(); /** * Get one auto-increment Id in spaceId. diff --git a/src/meta/processors/admin/AdminClient.cpp b/src/meta/processors/admin/AdminClient.cpp index c8d6ce43ace..61fe5cf001e 100644 --- a/src/meta/processors/admin/AdminClient.cpp +++ b/src/meta/processors/admin/AdminClient.cpp @@ -710,7 +710,7 @@ folly::Future AdminClient::addTask(cpp2::AdminCmd cmd, if (targetHost.empty()) { auto activeHostsRet = ActiveHostsMan::getActiveAdminHosts(kv_); if (!nebula::ok(activeHostsRet)) { - pro.setValue(Status::Error("Get actice hosts failed")); + pro.setValue(Status::Error("Get active hosts failed")); return f; } else { hosts = nebula::value(activeHostsRet); @@ -728,7 +728,7 @@ folly::Future AdminClient::addTask(cpp2::AdminCmd cmd, storage::cpp2::TaskPara para; para.set_space_id(spaceId); para.set_parts(std::move(parts)); - para.set_task_specfic_paras(taskSpecficParas); + para.set_task_specific_paras(taskSpecficParas); req.set_para(std::move(para)); std::function respGen = @@ -759,7 +759,7 @@ folly::Future AdminClient::stopTask(const std::vector& target, if (target.empty()) { auto activeHostsRet = ActiveHostsMan::getActiveAdminHosts(kv_); if (!nebula::ok(activeHostsRet)) { - pro.setValue(Status::Error("Get actice hosts failed")); + pro.setValue(Status::Error("Get active hosts failed")); return f; } else { hosts = nebula::value(activeHostsRet); diff --git a/src/meta/processors/admin/Balancer.cpp b/src/meta/processors/admin/Balancer.cpp new file mode 100644 index 00000000000..8cdad02b45a --- /dev/null +++ b/src/meta/processors/admin/Balancer.cpp @@ -0,0 +1,1232 @@ +/* Copyright (c) 2019 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#include "meta/processors/admin/Balancer.h" + +#include + +#include +#include + +#include "common/network/NetworkUtils.h" +#include "common/utils/MetaKeyUtils.h" +#include "kvstore/NebulaStore.h" +#include "meta/ActiveHostsMan.h" +#include "meta/common/MetaCommon.h" +#include "meta/processors/Common.h" + +DEFINE_double(leader_balance_deviation, + 0.05, + "after leader balance, leader count should in range " + "[avg * (1 - deviation), avg * (1 + deviation)]"); + +namespace nebula { +namespace meta { + +ErrorOr Balancer::balance(std::vector&& lostHosts) { + std::lock_guard lg(lock_); + if (!running_) { + auto retCode = recovery(); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Recovery balancer failed!"; + finish(); + return retCode; + } + if (plan_ == nullptr) { + LOG(INFO) << "There is no corrupted plan need to recovery, so create a new one"; + retCode = buildBalancePlan(std::move(lostHosts)); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Create balance plan failed"; + finish(); + return retCode; + } + } + LOG(INFO) << "Start to invoke balance plan " << plan_->id(); + executor_->add(std::bind(&BalancePlan::invoke, plan_.get())); + running_ = true; + return plan_->id(); + } + CHECK(!!plan_); + LOG(INFO) << "Balance plan " << plan_->id() << " is still running"; + return plan_->id(); +} + +ErrorOr Balancer::show(BalanceID id) const { + std::lock_guard lg(lock_); + if (plan_ != nullptr && plan_->id() == id) { + return *plan_; + } + + if (kv_) { + BalancePlan plan(id, kv_, client_); + auto retCode = plan.recovery(false); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Get balance plan failed, id " << id; + return retCode; + } + return plan; + } + return nebula::cpp2::ErrorCode::E_KEY_NOT_FOUND; +} + +ErrorOr Balancer::stop() { + std::lock_guard lg(lock_); + if (!running_) { + return nebula::cpp2::ErrorCode::E_KEY_NOT_FOUND; + } + CHECK(!!plan_); + plan_->stop(); + LOG(INFO) << "Stop balance plan " << plan_->id(); + return plan_->id(); +} + +ErrorOr Balancer::cleanLastInValidPlan() { + std::lock_guard lg(lock_); + auto* store = static_cast(kv_); + if (!store->isLeader(kDefaultSpaceId, kDefaultPartId)) { + return nebula::cpp2::ErrorCode::E_LEADER_CHANGED; + } + if (running_) { + return nebula::cpp2::ErrorCode::E_BALANCER_RUNNING; + } + const auto& prefix = MetaKeyUtils::balancePlanPrefix(); + std::unique_ptr iter; + auto retCode = kv_->prefix(kDefaultSpaceId, kDefaultPartId, prefix, &iter); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Can't access kvstore, ret = " << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + // There should be at most one invalid plan, and it must be the latest one + if (iter->valid()) { + auto status = MetaKeyUtils::parseBalanceStatus(iter->val()); + if (status == BalanceStatus::FAILED) { + auto balanceId = MetaKeyUtils::parseBalanceID(iter->key()); + folly::Baton baton; + auto result = nebula::cpp2::ErrorCode::SUCCEEDED; + // Only remove the plan will be enough + kv_->asyncMultiRemove(kDefaultSpaceId, + kDefaultPartId, + {iter->key().str()}, + [&baton, &result](nebula::cpp2::ErrorCode code) { + result = code; + baton.post(); + }); + baton.wait(); + if (result != nebula::cpp2::ErrorCode::SUCCEEDED) { + return result; + } + return balanceId; + } + } + return nebula::cpp2::ErrorCode::E_NO_INVALID_BALANCE_PLAN; +} + +nebula::cpp2::ErrorCode Balancer::recovery() { + CHECK(!plan_) << "plan should be nullptr now"; + if (kv_) { + auto* store = static_cast(kv_); + if (!store->isLeader(kDefaultSpaceId, kDefaultPartId)) { + // We need to check whether is leader or not, otherwise we would failed to + // persist state of BalancePlan and BalanceTask, so we just reject request + // if not leader. + return nebula::cpp2::ErrorCode::E_LEADER_CHANGED; + } + const auto& prefix = MetaKeyUtils::balancePlanPrefix(); + std::unique_ptr iter; + auto retCode = kv_->prefix(kDefaultSpaceId, kDefaultPartId, prefix, &iter); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Can't access kvstore, ret = " << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + std::vector corruptedPlans; + // The balance plan is stored with balance id desc order, there should be at + // most one failed or in_progress plan, and it must be the latest one + if (iter->valid()) { + auto status = MetaKeyUtils::parseBalanceStatus(iter->val()); + if (status == BalanceStatus::IN_PROGRESS || status == BalanceStatus::FAILED) { + auto balanceId = MetaKeyUtils::parseBalanceID(iter->key()); + corruptedPlans.emplace_back(balanceId); + } + } + if (corruptedPlans.empty()) { + LOG(INFO) << "No corrupted plan need to recovery!"; + return nebula::cpp2::ErrorCode::SUCCEEDED; + } + + CHECK_EQ(1, corruptedPlans.size()); + plan_ = std::make_unique(corruptedPlans[0], kv_, client_); + plan_->onFinished_ = [this]() { + auto self = plan_; + { + std::lock_guard lg(lock_); + if (LastUpdateTimeMan::update(kv_, time::WallClock::fastNowInMilliSec()) != + nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Balance plan " << plan_->id() << " update meta failed"; + } + finish(); + } + }; + auto recRet = plan_->recovery(); + if (recRet != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Can't recovery plan " << corruptedPlans[0]; + return recRet; + } + } + // save the balance plan again because FAILED tasks would be marked as + // IN_PROGRESS again + return plan_->saveInStore(); +} + +nebula::cpp2::ErrorCode Balancer::getAllSpaces( + std::vector>& spaces) { + // Get all spaces + folly::SharedMutex::ReadHolder rHolder(LockUtils::spaceLock()); + const auto& prefix = MetaKeyUtils::spacePrefix(); + std::unique_ptr iter; + auto retCode = kv_->prefix(kDefaultSpaceId, kDefaultPartId, prefix, &iter); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Get all spaces failed, error: " << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + + while (iter->valid()) { + auto spaceId = MetaKeyUtils::spaceId(iter->key()); + auto properties = MetaKeyUtils::parseSpace(iter->val()); + bool zoned = properties.group_name_ref().has_value(); + spaces.emplace_back(spaceId, *properties.replica_factor_ref(), zoned); + iter->next(); + } + return nebula::cpp2::ErrorCode::SUCCEEDED; +} + +nebula::cpp2::ErrorCode Balancer::buildBalancePlan(std::vector&& lostHosts) { + if (plan_ != nullptr) { + LOG(ERROR) << "Balance plan should be nullptr now"; + return nebula::cpp2::ErrorCode::E_BALANCED; + } + + std::vector> spaces; + auto spacesRet = getAllSpaces(spaces); + if (spacesRet != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Can't get all spaces"; + return spacesRet; + } + + plan_ = std::make_unique(time::WallClock::fastNowInSec(), kv_, client_); + for (const auto& spaceInfo : spaces) { + auto spaceId = std::get<0>(spaceInfo); + auto spaceReplica = std::get<1>(spaceInfo); + auto dependentOnGroup = std::get<2>(spaceInfo); + LOG(INFO) << "Balance Space " << spaceId; + auto taskRet = genTasks(spaceId, spaceReplica, dependentOnGroup, std::move(lostHosts)); + if (!ok(taskRet)) { + LOG(ERROR) << "Generate tasks on space " << std::get<0>(spaceInfo) << " failed"; + return error(taskRet); + } + + auto tasks = std::move(value(taskRet)); + for (auto& task : tasks) { + plan_->addTask(std::move(task)); + } + } + + plan_->onFinished_ = [this]() { + auto self = plan_; + { + std::lock_guard lg(lock_); + if (LastUpdateTimeMan::update(kv_, time::WallClock::fastNowInMilliSec()) != + nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Balance plan " << plan_->id() << " update meta failed"; + } + finish(); + } + }; + if (plan_->tasks_.empty()) { + return nebula::cpp2::ErrorCode::E_BALANCED; + } + return plan_->saveInStore(); +} + +ErrorOr> Balancer::genTasks( + GraphSpaceID spaceId, + int32_t spaceReplica, + bool dependentOnGroup, + std::vector&& lostHosts) { + HostParts hostParts; + int32_t totalParts = 0; + // hostParts is current part allocation map + auto result = getHostParts(spaceId, dependentOnGroup, hostParts, totalParts); + if (!nebula::ok(result)) { + return nebula::error(result); + } + + auto retVal = nebula::value(result); + if (!retVal || totalParts == 0 || hostParts.empty()) { + LOG(ERROR) << "Invalid space " << spaceId; + return nebula::cpp2::ErrorCode::E_KEY_NOT_FOUND; + } + + auto fetchHostPartsRet = fetchHostParts(spaceId, dependentOnGroup, hostParts, lostHosts); + if (!nebula::ok(fetchHostPartsRet)) { + LOG(ERROR) << "Fetch hosts and parts failed"; + return nebula::error(fetchHostPartsRet); + } + + auto hostPartsRet = nebula::value(fetchHostPartsRet); + auto confirmedHostParts = hostPartsRet.first; + auto activeHosts = hostPartsRet.second; + LOG(INFO) << "Now, try to balance the confirmedHostParts"; + + // We have two parts need to balance, the first one is parts on lost hosts and + // deleted hosts The seconds one is parts on unbalanced host in + // confirmedHostParts. + std::vector tasks; + // 1. Iterate through all hosts that would not be included in + // confirmedHostParts, + // move all parts in them to host with minimum part in confirmedHostParts + for (auto& lostHost : lostHosts) { + auto& lostParts = hostParts[lostHost]; + for (auto& partId : lostParts) { + LOG(INFO) << "Try balance part " << partId << " for lost host " << lostHost; + // check whether any peers which is alive + auto alive = checkReplica(hostParts, activeHosts, spaceReplica, partId); + if (!alive.ok()) { + LOG(ERROR) << "Check Replica failed: " << alive << " Part: " << partId; + return nebula::cpp2::ErrorCode::E_NO_VALID_HOST; + } + + auto retCode = + transferLostHost(tasks, confirmedHostParts, lostHost, spaceId, partId, dependentOnGroup); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Transfer lost host " << lostHost << " failed"; + return retCode; + } + } + } + + // 2. Make all hosts in confirmedHostParts balanced + if (balanceParts(plan_->id_, spaceId, confirmedHostParts, totalParts, tasks, dependentOnGroup)) { + return tasks; + } else { + return nebula::cpp2::ErrorCode::E_BAD_BALANCE_PLAN; + } +} + +nebula::cpp2::ErrorCode Balancer::transferLostHost(std::vector& tasks, + HostParts& confirmedHostParts, + const HostAddr& source, + GraphSpaceID spaceId, + PartitionID partId, + bool dependentOnGroup) { + // find a host with minimum parts which doesn't have this part + ErrorOr result; + if (dependentOnGroup) { + result = hostWithMinimalPartsForZone(source, confirmedHostParts, partId); + } else { + result = hostWithMinimalParts(confirmedHostParts, partId); + } + + if (!nebula::ok(result)) { + LOG(ERROR) << "Can't find a host which doesn't have part: " << partId; + return nebula::error(result); + } + const auto& targetHost = nebula::value(result); + confirmedHostParts[targetHost].emplace_back(partId); + tasks.emplace_back(plan_->id_, spaceId, partId, source, targetHost, kv_, client_); + zoneParts_[targetHost].second.emplace_back(partId); + auto zoneIt = + std::find(zoneParts_[source].second.begin(), zoneParts_[source].second.end(), partId); + if (zoneIt == zoneParts_[source].second.end()) { + LOG(ERROR) << "part not find " << partId << " at " << source; + } + return nebula::cpp2::ErrorCode::SUCCEEDED; +} + +ErrorOr>> +Balancer::fetchHostParts(GraphSpaceID spaceId, + bool dependentOnGroup, + const HostParts& hostParts, + std::vector& lostHosts) { + ErrorOr> activeHostsRet; + if (dependentOnGroup) { + activeHostsRet = ActiveHostsMan::getActiveHostsWithGroup(kv_, spaceId); + } else { + activeHostsRet = ActiveHostsMan::getActiveHosts(kv_); + } + + if (!nebula::ok(activeHostsRet)) { + return nebula::error(activeHostsRet); + } + + std::vector expand; + auto activeHosts = nebula::value(activeHostsRet); + calDiff(hostParts, activeHosts, expand, lostHosts); + // confirmedHostParts is new part allocation map after balance, it would + // include newlyAdded and exclude lostHosts + HostParts confirmedHostParts(hostParts); + for (const auto& h : expand) { + LOG(INFO) << "Found new host " << h; + confirmedHostParts.emplace(h, std::vector()); + } + for (const auto& h : lostHosts) { + LOG(INFO) << "Lost host " << h; + confirmedHostParts.erase(h); + } + return std::make_pair(confirmedHostParts, activeHosts); +} + +bool Balancer::balanceParts(BalanceID balanceId, + GraphSpaceID spaceId, + HostParts& confirmedHostParts, + int32_t totalParts, + std::vector& tasks, + bool dependentOnGroup) { + auto avgLoad = static_cast(totalParts) / confirmedHostParts.size(); + VLOG(3) << "The expect avg load is " << avgLoad; + int32_t minLoad = std::floor(avgLoad); + int32_t maxLoad = std::ceil(avgLoad); + VLOG(3) << "The min load is " << minLoad << " max load is " << maxLoad; + + auto sortedHosts = sortedHostsByParts(confirmedHostParts); + if (sortedHosts.empty()) { + LOG(ERROR) << "Host is empty"; + return false; + } + + auto maxPartsHost = sortedHosts.back(); + auto minPartsHost = sortedHosts.front(); + auto& sourceHost = maxPartsHost.first; + auto& targetHost = minPartsHost.first; + if (innerBalance_) { + LOG(INFO) << "maxPartsHost.first " << maxPartsHost.first << " minPartsHost.first " + << minPartsHost.first; + while (!checkZoneLegal(maxPartsHost.first, minPartsHost.first)) { + sortedHosts.pop_back(); + maxPartsHost = sortedHosts.back(); + } + + auto& source = maxPartsHost.first; + auto iter = std::find_if(zoneParts_.begin(), zoneParts_.end(), [&source](const auto& pair) { + return source == pair.first; + }); + + auto& zoneName = iter->second.first; + int32_t hostsSize = zoneHosts_[zoneName].size(); + int32_t totalPartsZone = 0; + for (auto& host : zoneHosts_[zoneName]) { + auto it = confirmedHostParts.find(host); + if (it == confirmedHostParts.end()) { + LOG(ERROR) << "Host " << host << "not in confirmedHostParts"; + continue; + } + totalPartsZone += it->second.size(); + } + + avgLoad = static_cast(totalPartsZone) / hostsSize; + minLoad = std::floor(avgLoad); + maxLoad = std::ceil(avgLoad); + LOG(INFO) << "Update min and max loading Total parts in zone " << totalPartsZone + << ", total hosts " << hostsSize << " The expect avg load is " << avgLoad + << " The min load is " << minLoad << " max load is " << maxLoad; + } + + while (maxPartsHost.second > maxLoad || minPartsHost.second < minLoad) { + auto& partsFrom = confirmedHostParts[maxPartsHost.first]; + auto& partsTo = confirmedHostParts[minPartsHost.first]; + std::sort(partsFrom.begin(), partsFrom.end()); + std::sort(partsTo.begin(), partsTo.end()); + + LOG(INFO) << maxPartsHost.first << ":" << partsFrom.size() << " -> " << minPartsHost.first + << ":" << partsTo.size(); + std::vector diff; + std::set_difference(partsFrom.begin(), + partsFrom.end(), + partsTo.begin(), + partsTo.end(), + std::inserter(diff, diff.begin())); + bool noAction = true; + for (auto& partId : diff) { + LOG(INFO) << "partsFrom size " << partsFrom.size() << " partsTo size " << partsTo.size() + << " minLoad " << minLoad << " maxLoad " << maxLoad; + if (partsFrom.size() == partsTo.size() + 1 || + partsFrom.size() == static_cast(minLoad) || + partsTo.size() == static_cast(maxLoad)) { + VLOG(3) << "No need to move any parts from " << maxPartsHost.first << " to " + << minPartsHost.first; + break; + } + + LOG(INFO) << "[space:" << spaceId << ", part:" << partId << "] " << maxPartsHost.first << "->" + << minPartsHost.first; + auto it = std::find(partsFrom.begin(), partsFrom.end(), partId); + if (it == partsFrom.end()) { + LOG(ERROR) << "Part " << partId << " not found in partsFrom"; + return false; + } + + if (std::find(partsTo.begin(), partsTo.end(), partId) != partsTo.end()) { + LOG(ERROR) << "Part " << partId << " already existed in partsTo"; + return false; + } + + if (dependentOnGroup) { + if (!checkZoneLegal(sourceHost, targetHost)) { + LOG(INFO) << "sourceHost " << sourceHost << " targetHost " << targetHost + << " not same zone"; + + auto& parts = relatedParts_[targetHost]; + auto minIt = std::find(parts.begin(), parts.end(), partId); + if (minIt != parts.end()) { + LOG(INFO) << "Part " << partId << " have existed"; + continue; + } + } + + auto& sourceNoneName = zoneParts_[sourceHost].first; + auto sourceHosts = zoneHosts_.find(sourceNoneName); + for (auto& sh : sourceHosts->second) { + auto& parts = relatedParts_[sh]; + auto maxIt = std::find(parts.begin(), parts.end(), partId); + if (maxIt == parts.end()) { + LOG(INFO) << "Part " << partId << " not found on " << sh; + continue; + } + parts.erase(maxIt); + } + + auto& targetNoneName = zoneParts_[targetHost].first; + auto targetHosts = zoneHosts_.find(targetNoneName); + for (auto& th : targetHosts->second) { + relatedParts_[th].emplace_back(partId); + } + } + + partsFrom.erase(it); + partsTo.emplace_back(partId); + tasks.emplace_back( + balanceId, spaceId, partId, maxPartsHost.first, minPartsHost.first, kv_, client_); + noAction = false; + } + + if (noAction) { + LOG(INFO) << "Here is no action"; + break; + } + sortedHosts = sortedHostsByParts(confirmedHostParts); + maxPartsHost = sortedHosts.back(); + minPartsHost = sortedHosts.front(); + if (innerBalance_) { + while (!checkZoneLegal(maxPartsHost.first, minPartsHost.first)) { + sortedHosts.pop_back(); + maxPartsHost = sortedHosts.back(); + } + + auto& source = maxPartsHost.first; + auto iter = std::find_if(zoneParts_.begin(), zoneParts_.end(), [&source](const auto& pair) { + return source == pair.first; + }); + + auto& zoneName = iter->second.first; + int32_t hostsSize = zoneHosts_[zoneName].size(); + int32_t totalPartsZone = 0; + for (auto& host : zoneHosts_[zoneName]) { + auto it = confirmedHostParts.find(host); + if (it == confirmedHostParts.end()) { + LOG(ERROR) << "Host " << host << "not in confirmedHostParts"; + continue; + } + totalPartsZone += it->second.size(); + } + + avgLoad = static_cast(totalPartsZone) / hostsSize; + minLoad = std::floor(avgLoad); + maxLoad = std::ceil(avgLoad); + LOG(INFO) << "Update min and max loading Total parts in zone " << totalPartsZone + << ", total hosts " << hostsSize << " The expect avg load is " << avgLoad + << " The min load is " << minLoad << " max load is " << maxLoad; + } + } + LOG(INFO) << "Balance tasks num: " << tasks.size(); + for (auto& task : tasks) { + LOG(INFO) << task.taskIdStr(); + } + + relatedParts_.clear(); + return true; +} + +ErrorOr Balancer::getHostParts(GraphSpaceID spaceId, + bool dependentOnGroup, + HostParts& hostParts, + int32_t& totalParts) { + folly::SharedMutex::ReadHolder rHolder(LockUtils::spaceLock()); + const auto& prefix = MetaKeyUtils::partPrefix(spaceId); + std::unique_ptr iter; + auto retCode = kv_->prefix(kDefaultSpaceId, kDefaultPartId, prefix, &iter); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Access kvstore failed, spaceId " << spaceId << " " + << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + + while (iter->valid()) { + auto key = iter->key(); + PartitionID partId; + memcpy(&partId, key.data() + prefix.size(), sizeof(PartitionID)); + auto partHosts = MetaKeyUtils::parsePartVal(iter->val()); + for (auto& ph : partHosts) { + hostParts[ph].emplace_back(partId); + } + totalParts++; + iter->next(); + } + + LOG(INFO) << "Host size: " << hostParts.size(); + auto key = MetaKeyUtils::spaceKey(spaceId); + std::string value; + retCode = kv_->get(kDefaultSpaceId, kDefaultPartId, key, &value); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Access kvstore failed, spaceId " << spaceId + << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + + auto properties = MetaKeyUtils::parseSpace(value); + if (totalParts != properties.get_partition_num()) { + LOG(ERROR) << "Partition number not equals"; + LOG(ERROR) << totalParts << " : " << properties.get_partition_num(); + return false; + } + + int32_t replica = properties.get_replica_factor(); + LOG(INFO) << "Replica " << replica; + if (dependentOnGroup && properties.group_name_ref().has_value()) { + auto groupName = *properties.group_name_ref(); + auto groupKey = MetaKeyUtils::groupKey(groupName); + std::string groupValue; + retCode = kv_->get(kDefaultSpaceId, kDefaultPartId, groupKey, &groupValue); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Get group " << groupName + << " failed: " << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + + int32_t zoneSize = MetaKeyUtils::parseZoneNames(std::move(groupValue)).size(); + LOG(INFO) << "Zone Size " << zoneSize; + innerBalance_ = (replica == zoneSize); + + auto activeHostsRet = ActiveHostsMan::getActiveHostsWithGroup(kv_, spaceId); + if (!nebula::ok(activeHostsRet)) { + return nebula::error(activeHostsRet); + } + + std::vector expand; + auto activeHosts = nebula::value(activeHostsRet); + std::vector lostHosts; + calDiff(hostParts, activeHosts, expand, lostHosts); + // confirmedHostParts is new part allocation map after balance, it would include newlyAdded + // and exclude lostHosts + HostParts confirmedHostParts(hostParts); + for (const auto& h : expand) { + LOG(INFO) << "Found new host " << h; + confirmedHostParts.emplace(h, std::vector()); + } + for (const auto& h : lostHosts) { + LOG(INFO) << "Lost host " << h; + confirmedHostParts.erase(h); + } + + auto zonePartsRet = assembleZoneParts(groupName, confirmedHostParts); + if (zonePartsRet != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Assemble Zone Parts failed group: " << groupName; + return zonePartsRet; + } + } + + totalParts *= replica; + return true; +} + +nebula::cpp2::ErrorCode Balancer::assembleZoneParts(const std::string& groupName, + HostParts& hostParts) { + LOG(INFO) << "Balancer assembleZoneParts"; + auto groupKey = MetaKeyUtils::groupKey(groupName); + std::string groupValue; + auto retCode = kv_->get(kDefaultSpaceId, kDefaultPartId, groupKey, &groupValue); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Get group " << groupName + << " failed: " << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + + // zoneHosts use to record this host belong to zone's hosts + std::unordered_map, std::vector> zoneHosts; + auto zoneNames = MetaKeyUtils::parseZoneNames(std::move(groupValue)); + for (auto zoneName : zoneNames) { + LOG(INFO) << "Zone Name: " << zoneName; + auto zoneKey = MetaKeyUtils::zoneKey(zoneName); + std::string zoneValue; + retCode = kv_->get(kDefaultSpaceId, kDefaultPartId, zoneKey, &zoneValue); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Get zone " << zoneName + << " failed: " << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + + auto hosts = MetaKeyUtils::parseZoneHosts(std::move(zoneValue)); + for (const auto& host : hosts) { + LOG(INFO) << "Host for zone " << host; + auto pair = std::pair(std::move(host), zoneName); + auto& hs = zoneHosts[std::move(pair)]; + hs.insert(hs.end(), hosts.begin(), hosts.end()); + } + } + + for (auto it = hostParts.begin(); it != hostParts.end(); it++) { + auto host = it->first; + LOG(INFO) << "Host: " << host; + auto zoneIter = + std::find_if(zoneHosts.begin(), zoneHosts.end(), [host](const auto& pair) -> bool { + return host == pair.first.first; + }); + + if (zoneIter == zoneHosts.end()) { + LOG(INFO) << it->first << " have lost"; + continue; + } + + auto& hosts = zoneIter->second; + auto name = zoneIter->first.second; + zoneHosts_[name] = hosts; + for (auto hostIter = hosts.begin(); hostIter != hosts.end(); hostIter++) { + auto partIter = hostParts.find(*hostIter); + LOG(INFO) << "Zone " << name << " have the host " << it->first; + if (partIter == hostParts.end()) { + zoneParts_[it->first] = ZoneNameAndParts(name, std::vector()); + } else { + zoneParts_[it->first] = ZoneNameAndParts(name, partIter->second); + } + } + } + + for (auto it = zoneHosts.begin(); it != zoneHosts.end(); it++) { + auto host = it->first.first; + auto& hosts = it->second; + for (auto hostIter = hosts.begin(); hostIter != hosts.end(); hostIter++) { + auto h = *hostIter; + auto iter = std::find_if(hostParts.begin(), hostParts.end(), [h](const auto& pair) -> bool { + return h == pair.first; + }); + + if (iter == hostParts.end()) { + continue; + } + + auto& parts = iter->second; + auto& hp = relatedParts_[host]; + hp.insert(hp.end(), parts.begin(), parts.end()); + } + } + return nebula::cpp2::ErrorCode::SUCCEEDED; +} + +void Balancer::calDiff(const HostParts& hostParts, + const std::vector& activeHosts, + std::vector& expand, + std::vector& lost) { + for (auto it = hostParts.begin(); it != hostParts.end(); it++) { + VLOG(1) << "Original Host " << it->first << ", parts " << it->second.size(); + if (std::find(activeHosts.begin(), activeHosts.end(), it->first) == activeHosts.end() && + std::find(lost.begin(), lost.end(), it->first) == lost.end()) { + lost.emplace_back(it->first); + } + } + for (auto& h : activeHosts) { + VLOG(1) << "Active host " << h; + if (hostParts.find(h) == hostParts.end()) { + expand.emplace_back(h); + } + } +} + +std::vector> Balancer::sortedHostsByParts(const HostParts& hostParts) { + std::vector> hosts; + for (auto it = hostParts.begin(); it != hostParts.end(); it++) { + LOG(INFO) << "Host " << it->first << " parts " << it->second.size(); + hosts.emplace_back(it->first, it->second.size()); + } + std::sort(hosts.begin(), hosts.end(), [](const auto& l, const auto& r) { + if (l.second != r.second) { + return l.second < r.second; + } else { + return l.first.host < r.first.host; + } + }); + return hosts; +} + +Status Balancer::checkReplica(const HostParts& hostParts, + const std::vector& activeHosts, + int32_t replica, + PartitionID partId) { + // check host hold the part and alive + auto checkPart = [&](const auto& entry) { + auto& host = entry.first; + auto& parts = entry.second; + return std::find(parts.begin(), parts.end(), partId) != parts.end() && + std::find(activeHosts.begin(), activeHosts.end(), host) != activeHosts.end(); + }; + auto aliveReplica = std::count_if(hostParts.begin(), hostParts.end(), checkPart); + if (aliveReplica >= replica / 2 + 1) { + return Status::OK(); + } + return Status::Error("Not enough alive host hold the part %d", partId); +} + +ErrorOr Balancer::hostWithMinimalParts( + const HostParts& hostParts, PartitionID partId) { + auto hosts = sortedHostsByParts(hostParts); + for (auto& h : hosts) { + auto it = hostParts.find(h.first); + if (it == hostParts.end()) { + LOG(ERROR) << "Host " << h.first << " not found"; + return nebula::cpp2::ErrorCode::E_NO_HOSTS; + } + + if (std::find(it->second.begin(), it->second.end(), partId) == it->second.end()) { + return h.first; + } + } + return nebula::cpp2::ErrorCode::E_NO_HOSTS; +} + +ErrorOr Balancer::hostWithMinimalPartsForZone( + const HostAddr& source, const HostParts& hostParts, PartitionID partId) { + auto hosts = sortedHostsByParts(hostParts); + for (auto& h : hosts) { + auto it = hostParts.find(h.first); + if (it == hostParts.end()) { + LOG(ERROR) << "Host " << h.first << " not found"; + return nebula::cpp2::ErrorCode::E_NO_HOSTS; + } + + LOG(INFO) << "source " << source << " h.first " << h.first; + if (std::find(it->second.begin(), it->second.end(), partId) == it->second.end()) { + return h.first; + } + } + return nebula::cpp2::ErrorCode::E_NO_HOSTS; +} + +nebula::cpp2::ErrorCode Balancer::leaderBalance() { + if (running_) { + LOG(INFO) << "Balance process still running"; + return nebula::cpp2::ErrorCode::E_BALANCER_RUNNING; + } + + folly::Promise promise; + auto future = promise.getFuture(); + // Space ID, Replica Factor and Dependent On Group + std::vector> spaces; + auto ret = getAllSpaces(spaces); + if (ret != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Can't get spaces"; + // TODO unify error code + if (ret != nebula::cpp2::ErrorCode::E_LEADER_CHANGED) { + ret = nebula::cpp2::ErrorCode::E_STORE_FAILURE; + } + return ret; + } + + bool expected = false; + if (inLeaderBalance_.compare_exchange_strong(expected, true)) { + hostLeaderMap_.reset(new HostLeaderMap); + auto status = client_->getLeaderDist(hostLeaderMap_.get()).get(); + if (!status.ok() || hostLeaderMap_->empty()) { + LOG(ERROR) << "Get leader distribution failed"; + inLeaderBalance_ = false; + return nebula::cpp2::ErrorCode::E_RPC_FAILURE; + } + + std::vector> futures; + for (const auto& spaceInfo : spaces) { + auto spaceId = std::get<0>(spaceInfo); + auto replicaFactor = std::get<1>(spaceInfo); + auto dependentOnGroup = std::get<2>(spaceInfo); + LeaderBalancePlan plan; + auto balanceResult = buildLeaderBalancePlan( + hostLeaderMap_.get(), spaceId, replicaFactor, dependentOnGroup, plan); + if (!nebula::ok(balanceResult) || !nebula::value(balanceResult)) { + LOG(ERROR) << "Building leader balance plan failed " + << "Space: " << spaceId; + continue; + } + simplifyLeaderBalancePlan(spaceId, plan); + for (const auto& task : plan) { + futures.emplace_back(client_->transLeader(std::get<0>(task), + std::get<1>(task), + std::move(std::get<2>(task)), + std::move(std::get<3>(task)))); + } + } + + int32_t failed = 0; + folly::collectAll(futures) + .via(executor_.get()) + .thenTry([&](const auto& result) { + auto tries = result.value(); + for (const auto& t : tries) { + if (!t.value().ok()) { + ++failed; + } + } + }) + .wait(); + + inLeaderBalance_ = false; + if (failed != 0) { + LOG(ERROR) << failed << " partition failed to transfer leader"; + } + return nebula::cpp2::ErrorCode::SUCCEEDED; + } + return nebula::cpp2::ErrorCode::E_BALANCER_RUNNING; +} + +ErrorOr Balancer::buildLeaderBalancePlan( + HostLeaderMap* hostLeaderMap, + GraphSpaceID spaceId, + int32_t replicaFactor, + bool dependentOnGroup, + LeaderBalancePlan& plan, + bool useDeviation) { + PartAllocation peersMap; + HostParts leaderHostParts; + size_t leaderParts = 0; + // store peers of all partitions in peerMap + folly::SharedMutex::ReadHolder rHolder(LockUtils::spaceLock()); + const auto& prefix = MetaKeyUtils::partPrefix(spaceId); + std::unique_ptr iter; + auto retCode = kv_->prefix(kDefaultSpaceId, kDefaultPartId, prefix, &iter); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Access kvstore failed, spaceId " << spaceId << static_cast(retCode); + return retCode; + } + + while (iter->valid()) { + auto key = iter->key(); + PartitionID partId; + memcpy(&partId, key.data() + prefix.size(), sizeof(PartitionID)); + auto peers = MetaKeyUtils::parsePartVal(iter->val()); + peersMap[partId] = std::move(peers); + ++leaderParts; + iter->next(); + } + + int32_t totalParts = 0; + HostParts allHostParts; + auto result = getHostParts(spaceId, dependentOnGroup, allHostParts, totalParts); + if (!nebula::ok(result)) { + return nebula::error(result); + } else { + auto retVal = nebula::value(result); + if (!retVal || totalParts == 0 || allHostParts.empty()) { + LOG(ERROR) << "Invalid space " << spaceId; + return false; + } + } + + std::unordered_set activeHosts; + for (const auto& host : *hostLeaderMap) { + // only balance leader between hosts which have valid partition + if (!allHostParts[host.first].empty()) { + activeHosts.emplace(host.first); + leaderHostParts[host.first] = (*hostLeaderMap)[host.first][spaceId]; + } + } + + if (activeHosts.empty()) { + LOG(ERROR) << "No active hosts"; + return false; + } + + if (dependentOnGroup) { + for (auto it = allHostParts.begin(); it != allHostParts.end(); it++) { + auto min = it->second.size() / replicaFactor; + VLOG(3) << "Host: " << it->first << " Bounds: " << min << " : " << min + 1; + hostBounds_[it->first] = std::make_pair(min, min + 1); + } + } else { + size_t activeSize = activeHosts.size(); + size_t globalAvg = leaderParts / activeSize; + size_t globalMin = globalAvg; + size_t globalMax = globalAvg; + if (leaderParts % activeSize != 0) { + globalMax += 1; + } + + if (useDeviation) { + globalMin = std::ceil(static_cast(leaderParts) / activeSize * + (1 - FLAGS_leader_balance_deviation)); + globalMax = std::floor(static_cast(leaderParts) / activeSize * + (1 + FLAGS_leader_balance_deviation)); + } + VLOG(3) << "Build leader balance plan, expected min load: " << globalMin + << ", max load: " << globalMax << " avg: " << globalAvg; + + for (auto it = allHostParts.begin(); it != allHostParts.end(); it++) { + hostBounds_[it->first] = std::make_pair(globalMin, globalMax); + } + } + + while (true) { + int32_t taskCount = 0; + bool hasUnbalancedHost = false; + for (const auto& hostEntry : leaderHostParts) { + auto host = hostEntry.first; + auto& hostMinLoad = hostBounds_[host].first; + auto& hostMaxLoad = hostBounds_[host].second; + int32_t partSize = hostEntry.second.size(); + if (hostMinLoad <= partSize && partSize <= hostMaxLoad) { + VLOG(3) << partSize << " is between min load " << hostMinLoad << " and max load " + << hostMaxLoad; + continue; + } + + hasUnbalancedHost = true; + if (partSize < hostMinLoad) { + // need to acquire leader from other hosts + LOG(INFO) << "Acquire leaders to host: " << host << " loading: " << partSize + << " min loading " << hostMinLoad; + taskCount += acquireLeaders( + allHostParts, leaderHostParts, peersMap, activeHosts, host, plan, spaceId); + } else { + // need to transfer leader to other hosts + LOG(INFO) << "Giveup leaders from host: " << host << " loading: " << partSize + << " max loading " << hostMaxLoad; + taskCount += giveupLeaders(leaderHostParts, peersMap, activeHosts, host, plan, spaceId); + } + } + + // If every host is balanced or no more task during this loop, then the plan + // is done + if (!hasUnbalancedHost || taskCount == 0) { + LOG(INFO) << "Not need balance"; + break; + } + } + return true; +} + +int32_t Balancer::acquireLeaders(HostParts& allHostParts, + HostParts& leaderHostParts, + PartAllocation& peersMap, + std::unordered_set& activeHosts, + const HostAddr& target, + LeaderBalancePlan& plan, + GraphSpaceID spaceId) { + // host will loop for the partition which is not leader, and try to acquire the + // leader + int32_t taskCount = 0; + std::vector diff; + std::set_difference(allHostParts[target].begin(), + allHostParts[target].end(), + leaderHostParts[target].begin(), + leaderHostParts[target].end(), + std::back_inserter(diff)); + auto& targetLeaders = leaderHostParts[target]; + size_t minLoad = hostBounds_[target].first; + for (const auto& partId : diff) { + VLOG(3) << "Try acquire leader for part " << partId; + // find the leader of partId + auto sources = peersMap[partId]; + for (const auto& source : sources) { + if (source == target || !activeHosts.count(source)) { + continue; + } + + // if peer is the leader of partId and can transfer, then transfer it to + // host + auto& sourceLeaders = leaderHostParts[source]; + VLOG(3) << "Check peer: " << source << " min load: " << minLoad + << " peerLeaders size: " << sourceLeaders.size(); + auto it = std::find(sourceLeaders.begin(), sourceLeaders.end(), partId); + if (it != sourceLeaders.end() && minLoad < sourceLeaders.size()) { + sourceLeaders.erase(it); + targetLeaders.emplace_back(partId); + plan.emplace_back(spaceId, partId, source, target); + LOG(INFO) << "acquire plan trans leader space: " << spaceId << " part: " << partId + << " from " << source.host << ":" << source.port << " to " << target.host << ":" + << target.port; + ++taskCount; + break; + } + } + + // if host has enough leader, just return + if (targetLeaders.size() == minLoad) { + LOG(INFO) << "Host: " << target << "'s leader reach " << minLoad; + break; + } + } + return taskCount; +} + +int32_t Balancer::giveupLeaders(HostParts& leaderParts, + PartAllocation& peersMap, + std::unordered_set& activeHosts, + const HostAddr& source, + LeaderBalancePlan& plan, + GraphSpaceID spaceId) { + int32_t taskCount = 0; + auto& sourceLeaders = leaderParts[source]; + size_t maxLoad = hostBounds_[source].second; + + // host will try to transfer the extra leaders to other peers + for (auto it = sourceLeaders.begin(); it != sourceLeaders.end();) { + // find the leader of partId + auto partId = *it; + const auto& targets = peersMap[partId]; + bool isErase = false; + + // leader should move to the peer with lowest loading + auto target = + std::min_element(targets.begin(), targets.end(), [&](const auto& l, const auto& r) -> bool { + if (source == l || !activeHosts.count(l)) { + return false; + } + return leaderParts[l].size() < leaderParts[r].size(); + }); + + // If peer can accept this partition leader, than host will transfer to the + // peer + if (target != targets.end()) { + auto& targetLeaders = leaderParts[*target]; + int32_t targetLeaderSize = targetLeaders.size(); + if (targetLeaderSize < hostBounds_[*target].second) { + it = sourceLeaders.erase(it); + targetLeaders.emplace_back(partId); + plan.emplace_back(spaceId, partId, source, *target); + LOG(INFO) << "giveup plan trans leader space: " << spaceId << " part: " << partId + << " from " << source.host << ":" << source.port << " to " << target->host << ":" + << target->port; + ++taskCount; + isErase = true; + } + } + + // if host has enough leader, just return + if (sourceLeaders.size() == maxLoad) { + LOG(INFO) << "Host: " << source << "'s leader reach " << maxLoad; + break; + } + + if (!isErase) { + ++it; + } + } + return taskCount; +} + +void Balancer::simplifyLeaderBalancePlan(GraphSpaceID spaceId, LeaderBalancePlan& plan) { + // Within a leader balance plan, a partition may be moved several times, but + // actually we only need to transfer the leadership of a partition from the + // first host to the last host, and ignore the intermediate ones + std::unordered_map buckets; + for (auto& task : plan) { + buckets[std::get<1>(task)].emplace_back(task); + } + plan.clear(); + for (const auto& partEntry : buckets) { + plan.emplace_back(spaceId, + partEntry.first, + std::get<2>(partEntry.second.front()), + std::get<3>(partEntry.second.back())); + } +} + +nebula::cpp2::ErrorCode Balancer::collectZoneParts(const std::string& groupName, + HostParts& hostParts) { + auto groupKey = MetaKeyUtils::groupKey(groupName); + std::string groupValue; + auto retCode = kv_->get(kDefaultSpaceId, kDefaultPartId, groupKey, &groupValue); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Get group " << groupName + << " failed, error: " << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + + // zoneHosts use to record this host belong to zone's hosts + std::unordered_map, std::vector> zoneHosts; + auto zoneNames = MetaKeyUtils::parseZoneNames(std::move(groupValue)); + for (auto zoneName : zoneNames) { + auto zoneKey = MetaKeyUtils::zoneKey(zoneName); + std::string zoneValue; + retCode = kv_->get(kDefaultSpaceId, kDefaultPartId, zoneKey, &zoneValue); + if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(ERROR) << "Get zone " << zoneName + << " failed, error: " << apache::thrift::util::enumNameSafe(retCode); + return retCode; + } + + auto hosts = MetaKeyUtils::parseZoneHosts(std::move(zoneValue)); + for (const auto& host : hosts) { + auto pair = std::pair(std::move(host), zoneName); + auto& hs = zoneHosts[std::move(pair)]; + hs.insert(hs.end(), hosts.begin(), hosts.end()); + } + } + + for (auto it = hostParts.begin(); it != hostParts.end(); it++) { + auto host = it->first; + auto zoneIter = + std::find_if(zoneHosts.begin(), zoneHosts.end(), [host](const auto& pair) -> bool { + return host == pair.first.first; + }); + + if (zoneIter == zoneHosts.end()) { + LOG(INFO) << it->first << " have lost"; + continue; + } + + auto& hosts = zoneIter->second; + auto name = zoneIter->first.second; + for (auto hostIter = hosts.begin(); hostIter != hosts.end(); hostIter++) { + auto partIter = hostParts.find(*hostIter); + if (partIter == hostParts.end()) { + zoneParts_[it->first] = ZoneNameAndParts(name, std::vector()); + } else { + zoneParts_[it->first] = ZoneNameAndParts(name, partIter->second); + } + } + } + return nebula::cpp2::ErrorCode::SUCCEEDED; +} + +bool Balancer::checkZoneLegal(const HostAddr& source, const HostAddr& target) { + VLOG(3) << "Check " << source << " : " << target; + auto sourceIter = std::find_if(zoneParts_.begin(), zoneParts_.end(), [&source](const auto& pair) { + return source == pair.first; + }); + + if (sourceIter == zoneParts_.end()) { + LOG(INFO) << "Source " << source << " not found"; + return false; + } + + auto targetIter = std::find_if(zoneParts_.begin(), zoneParts_.end(), [&target](const auto& pair) { + return target == pair.first; + }); + + if (targetIter == zoneParts_.end()) { + LOG(INFO) << "Target " << target << " not found"; + return false; + } + + LOG(INFO) << sourceIter->second.first << " : " << targetIter->second.first; + return sourceIter->second.first == targetIter->second.first; +} + +} // namespace meta +} // namespace nebula diff --git a/src/meta/processors/admin/Balancer.h b/src/meta/processors/admin/Balancer.h new file mode 100644 index 00000000000..4a5331ee2a4 --- /dev/null +++ b/src/meta/processors/admin/Balancer.h @@ -0,0 +1,269 @@ +/* Copyright (c) 2019 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#ifndef META_ADMIN_BALANCER_H_ +#define META_ADMIN_BALANCER_H_ + +#include +#include + +#include "common/network/NetworkUtils.h" +#include "common/time/WallClock.h" +#include "kvstore/KVStore.h" +#include "meta/processors/admin/AdminClient.h" +#include "meta/processors/admin/BalancePlan.h" +#include "meta/processors/admin/BalanceTask.h" + +namespace nebula { +namespace meta { + +using HostParts = std::unordered_map>; +using PartAllocation = std::unordered_map>; +using LeaderBalancePlan = std::vector>; +using ZoneNameAndParts = std::pair>; + +/** +There are two interfaces public: + * Balance: it will construct a balance plan and invoked it. If last balance +plan is not succeeded, it will + * try to resume it. + * + * Rollback: In many cases, if some plan failed forever, we call this interface +to rollback. + +Some notes: +1. Balance will generate balance plan according to current active hosts and +parts allocation +2. For the plan, we hope after moving the least parts , it will reach a +reasonable state. +3. Only one balance plan could be invoked at the same time. +4. Each balance plan has one id, and we could show the status by "balance id" +command and after FO, we could resume the balance plan by type "balance" again. +5. Each balance plan contains many balance tasks, the task represents the +minimum movement unit. +6. We save the whole balancePlan state in kvstore to do failover. +7. Each balance task contains serval steps. And it should be executed step by +step. +8. One task failed will result in the whole balance plan failed. +9. Currently, we hope tasks for the same part could be invoked serially + * */ +class Balancer { + FRIEND_TEST(BalanceTest, BalancePartsTest); + FRIEND_TEST(BalanceTest, NormalTest); + FRIEND_TEST(BalanceTest, SimpleTestWithZone); + FRIEND_TEST(BalanceTest, SpecifyHostTest); + FRIEND_TEST(BalanceTest, SpecifyMultiHostTest); + FRIEND_TEST(BalanceTest, MockReplaceMachineTest); + FRIEND_TEST(BalanceTest, SingleReplicaTest); + FRIEND_TEST(BalanceTest, TryToRecoveryTest); + FRIEND_TEST(BalanceTest, RecoveryTest); + FRIEND_TEST(BalanceTest, StopPlanTest); + FRIEND_TEST(BalanceTest, CleanLastInvalidBalancePlanTest); + FRIEND_TEST(BalanceTest, LeaderBalancePlanTest); + FRIEND_TEST(BalanceTest, SimpleLeaderBalancePlanTest); + FRIEND_TEST(BalanceTest, IntersectHostsLeaderBalancePlanTest); + FRIEND_TEST(BalanceTest, LeaderBalanceTest); + FRIEND_TEST(BalanceTest, ManyHostsLeaderBalancePlanTest); + FRIEND_TEST(BalanceTest, LeaderBalanceWithZoneTest); + FRIEND_TEST(BalanceTest, LeaderBalanceWithLargerZoneTest); + FRIEND_TEST(BalanceTest, LeaderBalanceWithComplexZoneTest); + FRIEND_TEST(BalanceTest, ExpansionZoneTest); + FRIEND_TEST(BalanceTest, ExpansionHostIntoZoneTest); + FRIEND_TEST(BalanceTest, ShrinkZoneTest); + FRIEND_TEST(BalanceTest, ShrinkHostFromZoneTest); + FRIEND_TEST(BalanceTest, BalanceWithComplexZoneTest); + FRIEND_TEST(BalanceIntegrationTest, LeaderBalanceTest); + FRIEND_TEST(BalanceIntegrationTest, BalanceTest); + + public: + static Balancer* instance(kvstore::KVStore* kv) { + static std::unique_ptr client(new AdminClient(kv)); + static std::unique_ptr balancer(new Balancer(kv, client.get())); + return balancer.get(); + } + + ~Balancer() = default; + + /* + * Return Error if reject the balance request, otherwise return balance id. + * */ + ErrorOr balance(std::vector&& lostHosts = {}); + + /** + * Show balance plan id status. + * */ + ErrorOr show(BalanceID id) const; + + /** + * Stop balance plan by canceling all waiting balance task. + * */ + ErrorOr stop(); + + /** + * Clean invalid plan, return the invalid plan key if any + * */ + ErrorOr cleanLastInValidPlan(); + + /** + * TODO(heng): rollback some balance plan. + */ + Status rollback(BalanceID id) { return Status::Error("unimplemented, %ld", id); } + + /** + * TODO(heng): Execute balance plan from outside. + * */ + Status execute(BalancePlan plan) { + UNUSED(plan); + return Status::Error("Unsupport it yet!"); + } + + /** + * TODO(heng): Execute specific balance plan by id. + * */ + Status execute(BalanceID id) { + UNUSED(id); + return Status::Error("Unsupport it yet!"); + } + + nebula::cpp2::ErrorCode leaderBalance(); + + void finish() { + CHECK(!lock_.try_lock()); + plan_.reset(); + running_ = false; + } + + bool isRunning() { + std::lock_guard lg(lock_); + return running_; + } + + private: + Balancer(kvstore::KVStore* kv, AdminClient* client) : kv_(kv), client_(client) { + executor_.reset(new folly::CPUThreadPoolExecutor(1)); + } + /* + * When the balancer failover, we should recovery the status. + * */ + nebula::cpp2::ErrorCode recovery(); + + /** + * Build balance plan and save it in kvstore. + * */ + nebula::cpp2::ErrorCode buildBalancePlan(std::vector&& lostHosts); + + ErrorOr> genTasks( + GraphSpaceID spaceId, + int32_t spaceReplica, + bool dependentOnGroup, + std::vector&& lostHosts); + + ErrorOr>> fetchHostParts( + GraphSpaceID spaceId, + bool dependentOnGroup, + const HostParts& hostParts, + std::vector& lostHosts); + + ErrorOr getHostParts(GraphSpaceID spaceId, + bool dependentOnGroup, + HostParts& hostParts, + int32_t& totalParts); + + nebula::cpp2::ErrorCode assembleZoneParts(const std::string& groupName, HostParts& hostParts); + + void calDiff(const HostParts& hostParts, + const std::vector& activeHosts, + std::vector& newlyAdded, + std::vector& lost); + + Status checkReplica(const HostParts& hostParts, + const std::vector& activeHosts, + int32_t replica, + PartitionID partId); + + ErrorOr hostWithMinimalParts(const HostParts& hostParts, + PartitionID partId); + + ErrorOr hostWithMinimalPartsForZone(const HostAddr& source, + const HostParts& hostParts, + PartitionID partId); + + bool balanceParts(BalanceID balanceId, + GraphSpaceID spaceId, + HostParts& newHostParts, + int32_t totalParts, + std::vector& tasks, + bool dependentOnGroup); + + nebula::cpp2::ErrorCode transferLostHost(std::vector& tasks, + HostParts& newHostParts, + const HostAddr& source, + GraphSpaceID spaceId, + PartitionID partId, + bool dependentOnGroup); + + std::vector> sortedHostsByParts(const HostParts& hostParts); + + nebula::cpp2::ErrorCode getAllSpaces( + std::vector>& spaces); + + ErrorOr buildLeaderBalancePlan(HostLeaderMap* hostLeaderMap, + GraphSpaceID spaceId, + int32_t replicaFactor, + bool dependentOnGroup, + LeaderBalancePlan& plan, + bool useDeviation = true); + + void simplifyLeaderBalancePlan(GraphSpaceID spaceId, LeaderBalancePlan& plan); + + int32_t acquireLeaders(HostParts& allHostParts, + HostParts& leaderHostParts, + PartAllocation& peersMap, + std::unordered_set& activeHosts, + const HostAddr& target, + LeaderBalancePlan& plan, + GraphSpaceID spaceId); + + int32_t giveupLeaders(HostParts& leaderHostParts, + PartAllocation& peersMap, + std::unordered_set& activeHosts, + const HostAddr& source, + LeaderBalancePlan& plan, + GraphSpaceID spaceId); + + nebula::cpp2::ErrorCode collectZoneParts(const std::string& groupName, HostParts& hostParts); + + bool checkZoneLegal(const HostAddr& source, const HostAddr& target); + + private: + std::atomic_bool running_{false}; + kvstore::KVStore* kv_{nullptr}; + AdminClient* client_{nullptr}; + // Current running plan. + std::shared_ptr plan_{nullptr}; + std::unique_ptr executor_; + std::atomic_bool inLeaderBalance_{false}; + + // Host => Graph => Partitions + std::unique_ptr hostLeaderMap_; + mutable std::mutex lock_; + + std::unordered_map> hostBounds_; + + // TODO: (darion) nesting map maybe better + std::unordered_map zoneParts_; + std::unordered_map> zoneHosts_; + + // if the space dependent on group, it use to record the partition + // contained in the zone related to the node. + std::unordered_map> relatedParts_; + + bool innerBalance_ = false; +}; + +} // namespace meta +} // namespace nebula + +#endif // META_ADMIN_BALANCER_H_ diff --git a/src/meta/processors/admin/CreateBackupProcessor.cpp b/src/meta/processors/admin/CreateBackupProcessor.cpp index 4ad2e9eb542..e2454366a5e 100644 --- a/src/meta/processors/admin/CreateBackupProcessor.cpp +++ b/src/meta/processors/admin/CreateBackupProcessor.cpp @@ -84,7 +84,7 @@ void CreateBackupProcessor::process(const cpp2::CreateBackupReq& req) { } JobManager* jobMgr = JobManager::getInstance(); - auto result = jobMgr->checkIndexJobRuning(); + auto result = jobMgr->checkIndexJobRunning(); if (!nebula::ok(result)) { LOG(ERROR) << "get Index status failed, not allowed to create backup."; handleErrorCode(nebula::error(result)); diff --git a/src/meta/processors/admin/CreateSnapshotProcessor.cpp b/src/meta/processors/admin/CreateSnapshotProcessor.cpp index 0af266ebb59..6e57a88b781 100644 --- a/src/meta/processors/admin/CreateSnapshotProcessor.cpp +++ b/src/meta/processors/admin/CreateSnapshotProcessor.cpp @@ -16,7 +16,7 @@ void CreateSnapshotProcessor::process(const cpp2::CreateSnapshotReq&) { // check the index rebuild. not allowed to create snapshot when index // rebuilding. JobManager* jobMgr = JobManager::getInstance(); - auto result = jobMgr->checkIndexJobRuning(); + auto result = jobMgr->checkIndexJobRunning(); if (!nebula::ok(result)) { handleErrorCode(nebula::error(result)); onFinished(); diff --git a/src/meta/processors/admin/HBProcessor.cpp b/src/meta/processors/admin/HBProcessor.cpp index fd535e3ec51..6abdb2eff1b 100644 --- a/src/meta/processors/admin/HBProcessor.cpp +++ b/src/meta/processors/admin/HBProcessor.cpp @@ -33,11 +33,11 @@ void HBProcessor::process(const cpp2::HBReq& req) { LOG(INFO) << "Receive heartbeat from " << host << ", role = " << apache::thrift::util::enumNameSafe(req.get_role()); if (req.get_role() == cpp2::HostRole::STORAGE) { - ClusterID peerCluserId = req.get_cluster_id(); - if (peerCluserId == 0) { + ClusterID peerClusterId = req.get_cluster_id(); + if (peerClusterId == 0) { LOG(INFO) << "Set clusterId for new host " << host << "!"; resp_.set_cluster_id(clusterId_); - } else if (peerCluserId != clusterId_) { + } else if (peerClusterId != clusterId_) { LOG(ERROR) << "Reject wrong cluster host " << host << "!"; handleErrorCode(nebula::cpp2::ErrorCode::E_WRONGCLUSTER); onFinished(); diff --git a/src/meta/processors/admin/VerifyClientVersionProcessor.cpp b/src/meta/processors/admin/VerifyClientVersionProcessor.cpp index bca4b824429..314ab2e9ec8 100644 --- a/src/meta/processors/admin/VerifyClientVersionProcessor.cpp +++ b/src/meta/processors/admin/VerifyClientVersionProcessor.cpp @@ -10,7 +10,7 @@ DEFINE_bool(enable_client_white_list, true, "Turn on/off the client white list."); DEFINE_string(client_white_list, nebula::getOriginVersion() + ":2.5.0:2.5.1:2.6.0", - "A white list for different client versions, seperate with colon."); + "A white list for different client versions, separate with colon."); namespace nebula { namespace meta { diff --git a/src/meta/processors/job/GetStatsProcessor.cpp b/src/meta/processors/job/GetStatsProcessor.cpp index 62065fa0a38..094d018cc7d 100644 --- a/src/meta/processors/job/GetStatsProcessor.cpp +++ b/src/meta/processors/job/GetStatsProcessor.cpp @@ -30,8 +30,8 @@ void GetStatsProcessor::process(const cpp2::GetStatsReq& req) { return; } auto statsItem = MetaKeyUtils::parseStatsVal(val); - auto statisJobStatus = statsItem.get_status(); - if (statisJobStatus != cpp2::JobStatus::FINISHED) { + auto statsJobStatus = statsItem.get_status(); + if (statsJobStatus != cpp2::JobStatus::FINISHED) { LOG(ERROR) << "SpaceId " << spaceId << " stats job is running or failed, please execute `show jobs' firstly."; handleErrorCode(nebula::cpp2::ErrorCode::E_JOB_NOT_FINISHED); diff --git a/src/meta/processors/job/JobManager.cpp b/src/meta/processors/job/JobManager.cpp index 8d53afd4430..2d15e262d3b 100644 --- a/src/meta/processors/job/JobManager.cpp +++ b/src/meta/processors/job/JobManager.cpp @@ -122,7 +122,7 @@ void JobManager::scheduleThread() { auto jobDescRet = JobDescription::loadJobDescription(opJobId.second, kvStore_); if (!nebula::ok(jobDescRet)) { LOG(ERROR) << "[JobManager] load an invalid job from queue " << opJobId.second; - continue; // leader change or archive happend + continue; // leader change or archive happened } auto jobDesc = nebula::value(jobDescRet); if (!jobDesc.setStatus(cpp2::JobStatus::RUNNING)) { @@ -334,8 +334,8 @@ nebula::cpp2::ErrorCode JobManager::reportTaskFinish(const cpp2::ReportTaskReq& "report to an in-active job manager, job={}, task={}", jobId, taskId); return nebula::cpp2::ErrorCode::E_UNKNOWN; } - // bacause the last task will update the job's status - // tasks shoule report once a time + // because the last task will update the job's status + // tasks should report once a time std::lock_guard lk(muReportFinish_); auto tasksRet = getAllTasks(jobId); if (!nebula::ok(tasksRet)) { @@ -691,7 +691,7 @@ ErrorOr JobManager::getSpaceId(const std: return *reinterpret_cast(val.c_str()); } -ErrorOr JobManager::checkIndexJobRuning() { +ErrorOr JobManager::checkIndexJobRunning() { std::unique_ptr iter; auto retCode = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, JobUtil::jobPrefix(), &iter); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { diff --git a/src/meta/processors/job/JobManager.h b/src/meta/processors/job/JobManager.h index ab9b2280269..8d9a2e8d188 100644 --- a/src/meta/processors/job/JobManager.h +++ b/src/meta/processors/job/JobManager.h @@ -102,14 +102,14 @@ class JobManager : public nebula::cpp::NonCopyable, public nebula::cpp::NonMovab size_t jobSize() const; // Tries to extract an element from the front of the highPriorityQueue_, - // if faild, then extract an element from lowPriorityQueue_. + // if failed, then extract an element from lowPriorityQueue_. // If the element is obtained, return true, otherwise return false. bool try_dequeue(std::pair& opJobId); // Enter different priority queues according to the command type void enqueue(const JbOp& op, const JobID& jobId, const cpp2::AdminCmd& cmd); - ErrorOr checkIndexJobRuning(); + ErrorOr checkIndexJobRunning(); nebula::cpp2::ErrorCode handleRemainingJobs(); diff --git a/src/meta/processors/job/MetaJobExecutor.cpp b/src/meta/processors/job/MetaJobExecutor.cpp index f41e8d4eb2a..4a1c648ed6a 100644 --- a/src/meta/processors/job/MetaJobExecutor.cpp +++ b/src/meta/processors/job/MetaJobExecutor.cpp @@ -84,7 +84,7 @@ ErrOrHosts MetaJobExecutor::getTargetHost(GraphSpaceID spaceId) { return retCode; } - // use vector instead of set because this can convient for next step + // use vector instead of set because this can convenient for next step std::unordered_map> hostAndPart; std::vector>> hosts; while (iter->valid()) { @@ -224,15 +224,15 @@ nebula::cpp2::ErrorCode MetaJobExecutor::execute() { } } - std::vector> futs; + std::vector> futures; for (auto& address : addresses) { // transform to the admin host auto h = Utils::getAdminAddrFromStoreAddr(address.first); - futs.emplace_back(executeInternal(std::move(h), std::move(address.second))); + futures.emplace_back(executeInternal(std::move(h), std::move(address.second))); } auto rc = nebula::cpp2::ErrorCode::SUCCEEDED; - auto tries = folly::collectAll(std::move(futs)).get(); + auto tries = folly::collectAll(std::move(futures)).get(); for (auto& t : tries) { if (t.hasException()) { LOG(ERROR) << t.exception().what(); diff --git a/src/meta/processors/job/StatsJobExecutor.cpp b/src/meta/processors/job/StatsJobExecutor.cpp index 26d50c7d1e9..ceab9a7b085 100644 --- a/src/meta/processors/job/StatsJobExecutor.cpp +++ b/src/meta/processors/job/StatsJobExecutor.cpp @@ -50,7 +50,7 @@ nebula::cpp2::ErrorCode StatsJobExecutor::prepare() { } space_ = nebula::value(spaceRet); - // Set the status of the statis job to running + // Set the status of the stats job to running cpp2::StatsItem statsItem; statsItem.set_status(cpp2::JobStatus::RUNNING); auto statsKey = MetaKeyUtils::statsKey(space_); @@ -158,7 +158,7 @@ nebula::cpp2::ErrorCode StatsJobExecutor::finish(bool exeSuccessed) { std::string val; auto ret = kvstore_->get(kDefaultSpaceId, kDefaultPartId, tempKey, &val); if (ret != nebula::cpp2::ErrorCode::SUCCEEDED) { - LOG(ERROR) << "Can't find the statis data, spaceId : " << space_; + LOG(ERROR) << "Can't find the stats data, spaceId : " << space_; return ret; } auto statsItem = MetaKeyUtils::parseStatsVal(val); @@ -170,7 +170,7 @@ nebula::cpp2::ErrorCode StatsJobExecutor::finish(bool exeSuccessed) { auto statsVal = MetaKeyUtils::statsVal(statsItem); auto retCode = save(statsKey, statsVal); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { - LOG(ERROR) << "Sace statis data failed, error " << apache::thrift::util::enumNameSafe(retCode); + LOG(ERROR) << "Sace stats data failed, error " << apache::thrift::util::enumNameSafe(retCode); return retCode; } return doRemove(tempKey); @@ -196,13 +196,13 @@ nebula::cpp2::ErrorCode StatsJobExecutor::stop() { auto tries = folly::collectAll(std::move(futures)).get(); if (std::any_of(tries.begin(), tries.end(), [](auto& t) { return t.hasException(); })) { - LOG(ERROR) << "statis job stop() RPC failure."; + LOG(ERROR) << "stats job stop() RPC failure."; return nebula::cpp2::ErrorCode::E_BALANCER_FAILURE; } for (const auto& t : tries) { if (!t.value().ok()) { - LOG(ERROR) << "Stop statis job Failed"; + LOG(ERROR) << "Stop stats job Failed"; return nebula::cpp2::ErrorCode::E_BALANCER_FAILURE; } } diff --git a/src/meta/processors/job/StatsJobExecutor.h b/src/meta/processors/job/StatsJobExecutor.h index 70bd028058b..a7e3e23ab2f 100644 --- a/src/meta/processors/job/StatsJobExecutor.h +++ b/src/meta/processors/job/StatsJobExecutor.h @@ -39,7 +39,7 @@ class StatsJobExecutor : public MetaJobExecutor { private: // Stats job writes an additional data. - // The additional data is written when the statis job passes the check + // The additional data is written when the stats job passes the check // function. Update this additional data when job finishes. nebula::cpp2::ErrorCode save(const std::string& key, const std::string& val); diff --git a/src/meta/processors/kv/RemoveProcessor.h b/src/meta/processors/kv/RemoveProcessor.h index d789c5b338e..652f79c0dbb 100644 --- a/src/meta/processors/kv/RemoveProcessor.h +++ b/src/meta/processors/kv/RemoveProcessor.h @@ -12,7 +12,7 @@ namespace nebula { namespace meta { /** - * Remove some rows in custorm kv operations. + * Remove some rows in custom kv operations. * */ class RemoveProcessor : public BaseProcessor { public: diff --git a/src/meta/processors/parts/DropSpaceProcessor.cpp b/src/meta/processors/parts/DropSpaceProcessor.cpp index 4b47e00fd94..b36f3b0c4b4 100644 --- a/src/meta/processors/parts/DropSpaceProcessor.cpp +++ b/src/meta/processors/parts/DropSpaceProcessor.cpp @@ -94,11 +94,11 @@ void DropSpaceProcessor::process(const cpp2::DropSpaceReq& req) { lstIter->next(); } - // 5. Delete related statis data - auto statiskey = MetaKeyUtils::statsKey(spaceId); - deleteKeys.emplace_back(statiskey); + // 5. Delete related stats data + auto statskey = MetaKeyUtils::statsKey(spaceId); + deleteKeys.emplace_back(statskey); - // 6. Delte related fulltext index meta data + // 6. Delete related fulltext index meta data auto ftPrefix = MetaKeyUtils::fulltextIndexPrefix(); auto ftRet = doPrefix(ftPrefix); if (!nebula::ok(ftRet)) { diff --git a/src/meta/processors/parts/ListHostsProcessor.cpp b/src/meta/processors/parts/ListHostsProcessor.cpp index 49d174fb65a..ef1e115f249 100644 --- a/src/meta/processors/parts/ListHostsProcessor.cpp +++ b/src/meta/processors/parts/ListHostsProcessor.cpp @@ -68,7 +68,7 @@ void ListHostsProcessor::process(const cpp2::ListHostsReq& req) { * now(2020-04-29), assume all metad have same gitInfoSHA * this will change if some day * meta.thrift support interface like getHostStatus() - * which return a bunch of host infomation + * which return a bunch of host information * it's not necessary add this interface only for gitInfoSHA * */ nebula::cpp2::ErrorCode ListHostsProcessor::allMetaHostsStatus() { @@ -79,7 +79,7 @@ nebula::cpp2::ErrorCode ListHostsProcessor::allMetaHostsStatus() { return retCode; } auto metaPeers = nebula::value(errOrPart)->peers(); - // transform raft port to servre port + // transform raft port to severe port for (auto& metaHost : metaPeers) { metaHost = Utils::getStoreAddrFromRaftAddr(metaHost); } diff --git a/src/meta/processors/schema/GetEdgeProcessor.cpp b/src/meta/processors/schema/GetEdgeProcessor.cpp index 9550d6f68b4..da8c371ab3f 100644 --- a/src/meta/processors/schema/GetEdgeProcessor.cpp +++ b/src/meta/processors/schema/GetEdgeProcessor.cpp @@ -25,7 +25,7 @@ void GetEdgeProcessor::process(const cpp2::GetEdgeReq& req) { auto edgeType = nebula::value(edgeTypeRet); std::string schemaValue; - // Get the lastest version + // Get the latest version if (ver < 0) { auto edgePrefix = MetaKeyUtils::schemaEdgePrefix(spaceId, edgeType); auto ret = doPrefix(edgePrefix); diff --git a/src/meta/processors/schema/GetTagProcessor.cpp b/src/meta/processors/schema/GetTagProcessor.cpp index 2d1ed2fd35f..16af1b78f2e 100644 --- a/src/meta/processors/schema/GetTagProcessor.cpp +++ b/src/meta/processors/schema/GetTagProcessor.cpp @@ -25,7 +25,7 @@ void GetTagProcessor::process(const cpp2::GetTagReq& req) { auto tagId = nebula::value(tagIdRet); std::string schemaValue; - // Get the lastest version + // Get the latest version if (ver < 0) { auto tagPrefix = MetaKeyUtils::schemaTagPrefix(spaceId, tagId); auto ret = doPrefix(tagPrefix); diff --git a/src/meta/processors/zone/DropGroupProcessor.cpp b/src/meta/processors/zone/DropGroupProcessor.cpp index 287ed659ba9..50f40385fa4 100644 --- a/src/meta/processors/zone/DropGroupProcessor.cpp +++ b/src/meta/processors/zone/DropGroupProcessor.cpp @@ -24,7 +24,7 @@ void DropGroupProcessor::process(const cpp2::DropGroupReq& req) { return; } - // If any space rely on this group, it should not be droped. + // If any space rely on this group, it should not be dropped. auto retCode = checkSpaceDependency(groupName); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { handleErrorCode(retCode); diff --git a/src/meta/processors/zone/DropZoneProcessor.cpp b/src/meta/processors/zone/DropZoneProcessor.cpp index 0fc4691c6a9..a6377879b93 100644 --- a/src/meta/processors/zone/DropZoneProcessor.cpp +++ b/src/meta/processors/zone/DropZoneProcessor.cpp @@ -24,7 +24,7 @@ void DropZoneProcessor::process(const cpp2::DropZoneReq& req) { return; } - // If zone belong to any group, it should not be droped. + // If zone belong to any group, it should not be dropped. auto retCode = checkGroupDependency(zoneName); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { handleErrorCode(retCode); diff --git a/src/meta/test/BalanceIntegrationTest.cpp b/src/meta/test/BalanceIntegrationTest.cpp index eb7c4c8a6a4..519862ef480 100644 --- a/src/meta/test/BalanceIntegrationTest.cpp +++ b/src/meta/test/BalanceIntegrationTest.cpp @@ -175,7 +175,7 @@ TEST(BalanceIntegrationTest, BalanceTest) { newMetaClient.get(), dataPath.c_str(), localIp, storagePort, true); LOG(INFO) << "Start a new storage server on " << storageAddr; } - LOG(INFO) << "Let's stop the last storage servcie " << storagePorts.back(); + LOG(INFO) << "Let's stop the last storage service " << storagePorts.back(); { metaClients.back()->stop(); serverContexts.back().reset(); @@ -203,7 +203,7 @@ TEST(BalanceIntegrationTest, BalanceTest) { int num = 0; std::string lastKey = ""; while (iter->valid()) { - // filter the multipule versions for data. + // filter the multiple versions for data. auto key = NebulaKeyUtils::keyWithNoVersion(iter->key()); if (lastKey == key) { iter->next(); diff --git a/src/meta/test/BalancerTest.cpp b/src/meta/test/BalancerTest.cpp index b18cf0016a7..2151d3f1341 100644 --- a/src/meta/test/BalancerTest.cpp +++ b/src/meta/test/BalancerTest.cpp @@ -1093,7 +1093,7 @@ TEST(BalanceTest, SpecifyMultiHostTest) { LOG(INFO) << "Rebalance finished!"; // In theory, there should be only 12 tasks, but in some environment, 13 tasks - // is generated. A parition is moved more than once from A -> B -> C, actually + // is generated. A partition is moved more than once from A -> B -> C, actually // A -> C is enough. verifyBalanceTask( kv, balancer.jobId_, BalanceTaskStatus::END, BalanceTaskResult::SUCCEEDED, partCount); @@ -1583,7 +1583,7 @@ TEST(BalanceTest, ManyHostsLeaderBalancePlanTest) { LeaderBalanceJobExecutor balancer( testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); - // chcek several times if they are balanced + // check several times if they are balanced for (int count = 0; count < 1; count++) { HostLeaderMap hostLeaderMap; // all part will random choose a leader diff --git a/src/meta/test/ConfigManTest.cpp b/src/meta/test/ConfigManTest.cpp index 1e48d01ec5d..e802317f89c 100644 --- a/src/meta/test/ConfigManTest.cpp +++ b/src/meta/test/ConfigManTest.cpp @@ -188,7 +188,7 @@ TEST(ConfigManTest, ConfigProcessorTest) { updated.set_name("nested"); updated.set_type(cpp2::ConfigType::NESTED); updated.set_mode(cpp2::ConfigMode::MUTABLE); - // update from consle as format of update list + // update from console as format of update list updated.set_value("max_background_jobs=8,level0_file_num_compaction_trigger=10"); cpp2::SetConfigReq req; diff --git a/src/meta/test/GetStatsTest.cpp b/src/meta/test/GetStatsTest.cpp index e4631e8c442..bc10498acb8 100644 --- a/src/meta/test/GetStatsTest.cpp +++ b/src/meta/test/GetStatsTest.cpp @@ -122,19 +122,19 @@ TEST_F(GetStatsTest, StatsJob) { TestUtils::assembleSpace(kv_.get(), 1, 1); GraphSpaceID spaceId = 1; std::vector paras{"test_space"}; - JobDescription statisJob(12, cpp2::AdminCmd::STATS, paras); + JobDescription statsJob(12, cpp2::AdminCmd::STATS, paras); NiceMock adminClient; jobMgr->adminClient_ = &adminClient; - auto rc = jobMgr->save(statisJob.jobKey(), statisJob.jobVal()); + auto rc = jobMgr->save(statsJob.jobKey(), statsJob.jobVal()); ASSERT_EQ(rc, nebula::cpp2::ErrorCode::SUCCEEDED); { // Job is not executed, job status is QUEUE. // Stats data does not exist. - auto job1Ret = JobDescription::loadJobDescription(statisJob.id_, kv_.get()); + auto job1Ret = JobDescription::loadJobDescription(statsJob.id_, kv_.get()); ASSERT_TRUE(nebula::ok(job1Ret)); auto job1 = nebula::value(job1Ret); - ASSERT_EQ(statisJob.id_, job1.id_); + ASSERT_EQ(statsJob.id_, job1.id_); ASSERT_EQ(cpp2::JobStatus::QUEUE, job1.status_); cpp2::GetStatsReq req; @@ -145,7 +145,7 @@ TEST_F(GetStatsTest, StatsJob) { auto resp = std::move(f).get(); ASSERT_NE(nebula::cpp2::ErrorCode::SUCCEEDED, resp.get_code()); - // Directly find statis data in kvstore, statis data does not exist. + // Directly find stats data in kvstore, stats data does not exist. auto key = MetaKeyUtils::statsKey(spaceId); std::string val; auto ret = kv_->get(kDefaultSpaceId, kDefaultPartId, key, &val); @@ -157,27 +157,27 @@ TEST_F(GetStatsTest, StatsJob) { ASSERT_EQ(retsav, nebula::cpp2::ErrorCode::SUCCEEDED); } - // Run statis job, job finished. - // Insert running status statis data in prepare function of runJobInternal. - // Update statis data to finished or failed status in finish function of + // Run stats job, job finished. + // Insert running status stats data in prepare function of runJobInternal. + // Update stats data to finished or failed status in finish function of // runJobInternal. - auto result = jobMgr->runJobInternal(statisJob, JobManager::JbOp::ADD); + auto result = jobMgr->runJobInternal(statsJob, JobManager::JbOp::ADD); ASSERT_TRUE(result); // JobManager does not set the job finished status in RunJobInternal function. - // But set statis data. - statisJob.setStatus(cpp2::JobStatus::FINISHED); - jobMgr->save(statisJob.jobKey(), statisJob.jobVal()); - auto jobId = statisJob.getJobId(); + // But set stats data. + statsJob.setStatus(cpp2::JobStatus::FINISHED); + jobMgr->save(statsJob.jobKey(), statsJob.jobVal()); + auto jobId = statsJob.getJobId(); auto statsKey = MetaKeyUtils::statsKey(spaceId); auto tempKey = toTempKey(spaceId, jobId); copyData(kv_.get(), 0, 0, statsKey, tempKey); jobMgr->jobFinished(jobId, cpp2::JobStatus::FINISHED); { - auto job2Ret = JobDescription::loadJobDescription(statisJob.id_, kv_.get()); + auto job2Ret = JobDescription::loadJobDescription(statsJob.id_, kv_.get()); ASSERT_TRUE(nebula::ok(job2Ret)); auto job2 = nebula::value(job2Ret); - ASSERT_EQ(statisJob.id_, job2.id_); + ASSERT_EQ(statsJob.id_, job2.id_); ASSERT_EQ(cpp2::JobStatus::FINISHED, job2.status_); cpp2::GetStatsReq req; @@ -198,7 +198,7 @@ TEST_F(GetStatsTest, StatsJob) { ASSERT_EQ(0, statsItem.get_space_vertices()); ASSERT_EQ(0, statsItem.get_space_edges()); - // Directly find statis data in kvstore, statis data exists. + // Directly find stats data in kvstore, stats data exists. auto key = MetaKeyUtils::statsKey(spaceId); std::string val; auto ret = kv_->get(kDefaultSpaceId, kDefaultPartId, key, &val); @@ -212,22 +212,22 @@ TEST_F(GetStatsTest, StatsJob) { ASSERT_EQ(0, statsItem1.get_space_edges()); } - // Execute new statis job in same space. + // Execute new stats job in same space. std::vector paras1{"test_space"}; - JobDescription statisJob2(13, cpp2::AdminCmd::STATS, paras1); - auto rc2 = jobMgr->save(statisJob2.jobKey(), statisJob2.jobVal()); + JobDescription statsJob2(13, cpp2::AdminCmd::STATS, paras1); + auto rc2 = jobMgr->save(statsJob2.jobKey(), statsJob2.jobVal()); ASSERT_EQ(rc2, nebula::cpp2::ErrorCode::SUCCEEDED); { // Job is not executed, job status is QUEUE. // Stats data exists, but it is the result of the last stats job // execution. - auto job1Ret = JobDescription::loadJobDescription(statisJob2.id_, kv_.get()); + auto job1Ret = JobDescription::loadJobDescription(statsJob2.id_, kv_.get()); ASSERT_TRUE(nebula::ok(job1Ret)); auto job1 = nebula::value(job1Ret); - ASSERT_EQ(statisJob2.id_, job1.id_); + ASSERT_EQ(statsJob2.id_, job1.id_); ASSERT_EQ(cpp2::JobStatus::QUEUE, job1.status_); - // Success, but statis data is the result of the last statis job. + // Success, but stats data is the result of the last stats job. cpp2::GetStatsReq req; req.set_space_id(spaceId); auto* processor = GetStatsProcessor::instance(kv_.get()); @@ -243,7 +243,7 @@ TEST_F(GetStatsTest, StatsJob) { ASSERT_EQ(0, statsItem.get_space_vertices()); ASSERT_EQ(0, statsItem.get_space_edges()); - // Directly find statis data in kvstore, statis data exists. + // Directly find stats data in kvstore, stats data exists. auto key = MetaKeyUtils::statsKey(spaceId); std::string val; auto ret = kv_->get(kDefaultSpaceId, kDefaultPartId, key, &val); @@ -262,7 +262,7 @@ TEST_F(GetStatsTest, StatsJob) { ASSERT_EQ(retsav, nebula::cpp2::ErrorCode::SUCCEEDED); } - // Remove statis data. + // Remove stats data. { auto key = MetaKeyUtils::statsKey(spaceId); folly::Baton baton; @@ -277,7 +277,7 @@ TEST_F(GetStatsTest, StatsJob) { baton.wait(); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, retCode); - // Directly find statis data in kvstore, statis data does not exist. + // Directly find stats data in kvstore, stats data does not exist. std::string val; auto ret = kv_->get(kDefaultSpaceId, kDefaultPartId, key, &val); ASSERT_NE(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -291,13 +291,13 @@ TEST_F(GetStatsTest, StatsJob) { ASSERT_NE(nebula::cpp2::ErrorCode::SUCCEEDED, resp.get_code()); } - // Run statis job. - // Insert running status statis data in prepare function of runJobInternal. - // Update statis data to finished or failed status in finish function of + // Run stats job. + // Insert running status stats data in prepare function of runJobInternal. + // Update stats data to finished or failed status in finish function of // runJobInternal. - auto result2 = jobMgr->runJobInternal(statisJob2, JobManager::JbOp::ADD); + auto result2 = jobMgr->runJobInternal(statsJob2, JobManager::JbOp::ADD); - auto jobId2 = statisJob2.getJobId(); + auto jobId2 = statsJob2.getJobId(); auto statsKey2 = MetaKeyUtils::statsKey(spaceId); auto tempKey2 = toTempKey(spaceId, jobId2); @@ -306,15 +306,15 @@ TEST_F(GetStatsTest, StatsJob) { ASSERT_TRUE(result2); // JobManager does not set the job finished status in RunJobInternal function. - // But set statis data. - statisJob2.setStatus(cpp2::JobStatus::FINISHED); - jobMgr->save(statisJob2.jobKey(), statisJob2.jobVal()); + // But set stats data. + statsJob2.setStatus(cpp2::JobStatus::FINISHED); + jobMgr->save(statsJob2.jobKey(), statsJob2.jobVal()); { - auto job2Ret = JobDescription::loadJobDescription(statisJob2.id_, kv_.get()); + auto job2Ret = JobDescription::loadJobDescription(statsJob2.id_, kv_.get()); ASSERT_TRUE(nebula::ok(job2Ret)); auto job2 = nebula::value(job2Ret); - ASSERT_EQ(statisJob2.id_, job2.id_); + ASSERT_EQ(statsJob2.id_, job2.id_); ASSERT_EQ(cpp2::JobStatus::FINISHED, job2.status_); cpp2::GetStatsReq req; @@ -332,7 +332,7 @@ TEST_F(GetStatsTest, StatsJob) { ASSERT_EQ(0, statsItem.get_space_vertices()); ASSERT_EQ(0, statsItem.get_space_edges()); - // Directly find statis data in kvstore, statis data exists. + // Directly find stats data in kvstore, stats data exists. auto key = MetaKeyUtils::statsKey(spaceId); std::string val; auto ret = kv_->get(kDefaultSpaceId, kDefaultPartId, key, &val); @@ -368,7 +368,7 @@ TEST_F(GetStatsTest, MockSingleMachineTest) { NiceMock adminClient; jobMgr->adminClient_ = &adminClient; - // add statis job1 + // add stats job1 JobID jobId1 = 1; std::vector paras{"test_space"}; JobDescription job1(jobId1, cpp2::AdminCmd::STATS, paras); @@ -417,7 +417,7 @@ TEST_F(GetStatsTest, MockSingleMachineTest) { ASSERT_EQ(200, statsItem.get_space_edges()); } - // add statis job2 of same space + // add stats job2 of same space JobID jobId2 = 2; JobDescription job2(jobId2, cpp2::AdminCmd::STATS, paras); jobMgr->addJob(job2, &adminClient); @@ -483,7 +483,7 @@ TEST_F(GetStatsTest, MockMultiMachineTest) { NiceMock adminClient; jobMgr->adminClient_ = &adminClient; - // add statis job + // add stats job JobID jobId = 1; std::vector paras{"test_space"}; JobDescription job(jobId, cpp2::AdminCmd::STATS, paras); diff --git a/src/meta/test/JobManagerTest.cpp b/src/meta/test/JobManagerTest.cpp index 855b8563cdc..9c910486c5c 100644 --- a/src/meta/test/JobManagerTest.cpp +++ b/src/meta/test/JobManagerTest.cpp @@ -82,7 +82,7 @@ TEST_F(JobManagerTest, addJob) { } TEST_F(JobManagerTest, AddRebuildTagIndexJob) { - // For preventting job schedule in JobManager + // For preventing job schedule in JobManager jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; std::vector paras{"tag_index_name", "test_space"}; @@ -94,7 +94,7 @@ TEST_F(JobManagerTest, AddRebuildTagIndexJob) { } TEST_F(JobManagerTest, AddRebuildEdgeIndexJob) { - // For preventting job schedule in JobManager + // For preventing job schedule in JobManager jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; std::vector paras{"edge_index_name", "test_space"}; @@ -106,7 +106,7 @@ TEST_F(JobManagerTest, AddRebuildEdgeIndexJob) { } TEST_F(JobManagerTest, StatsJob) { - // For preventting job schedule in JobManager + // For preventing job schedule in JobManager jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; std::vector paras{"test_space"}; @@ -127,7 +127,7 @@ TEST_F(JobManagerTest, StatsJob) { } TEST_F(JobManagerTest, JobPriority) { - // For preventting job schedule in JobManager + // For preventing job schedule in JobManager jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; ASSERT_EQ(0, jobMgr->jobSize()); @@ -162,7 +162,7 @@ TEST_F(JobManagerTest, JobPriority) { } TEST_F(JobManagerTest, JobDeduplication) { - // For preventting job schedule in JobManager + // For preventing job schedule in JobManager jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; ASSERT_EQ(0, jobMgr->jobSize()); diff --git a/src/meta/test/MetaClientTest.cpp b/src/meta/test/MetaClientTest.cpp index 2b6d791838b..a9e6d6f4723 100644 --- a/src/meta/test/MetaClientTest.cpp +++ b/src/meta/test/MetaClientTest.cpp @@ -2019,7 +2019,7 @@ TEST(MetaClientTest, Config) { configs = std::move(resp).value(); EXPECT_EQ(configs[0].get_value(), Value(3)); } - // Just avoid memory leak error of clang asan. to waitting asynchronous thread + // Just avoid memory leak error of clang asan. to waiting asynchronous thread // done. sleep(FLAGS_heartbeat_interval_secs * 5); } diff --git a/src/meta/test/ProcessorTest.cpp b/src/meta/test/ProcessorTest.cpp index 4e68688facf..49e252d53d4 100644 --- a/src/meta/test/ProcessorTest.cpp +++ b/src/meta/test/ProcessorTest.cpp @@ -897,7 +897,7 @@ TEST(ProcessorTest, CreateTagTest) { cpp2::CreateTagReq req; req.set_space_id(1); - req.set_tag_name("tag_type_mismatche"); + req.set_tag_name("tag_type_mismatch"); req.set_schema(std::move(schemaWithDefault)); auto* processor = CreateTagProcessor::instance(kv.get()); auto f = processor->getFuture(); @@ -921,7 +921,7 @@ TEST(ProcessorTest, CreateTagTest) { cpp2::CreateTagReq req; req.set_space_id(1); - req.set_tag_name("tag_value_mismatche"); + req.set_tag_name("tag_value_mismatch"); req.set_schema(std::move(schemaWithDefault)); auto* processor = CreateTagProcessor::instance(kv.get()); auto f = processor->getFuture(); @@ -1088,7 +1088,7 @@ TEST(ProcessorTest, CreateEdgeTest) { cpp2::CreateEdgeReq req; req.set_space_id(1); - req.set_edge_name("edge_with_defaule"); + req.set_edge_name("edge_with_default"); req.set_schema(std::move(schemaWithDefault)); auto* processor = CreateEdgeProcessor::instance(kv.get()); auto f = processor->getFuture(); @@ -1105,7 +1105,7 @@ TEST(ProcessorTest, CreateEdgeTest) { cpp2::CreateEdgeReq req; req.set_space_id(1); - req.set_edge_name("edge_type_mismatche"); + req.set_edge_name("edge_type_mismatch"); req.set_schema(std::move(schemaWithDefault)); auto* processor = CreateEdgeProcessor::instance(kv.get()); auto f = processor->getFuture(); diff --git a/src/parser/AdminSentences.h b/src/parser/AdminSentences.h index af043f2b880..c08c738d39f 100644 --- a/src/parser/AdminSentences.h +++ b/src/parser/AdminSentences.h @@ -230,7 +230,7 @@ class SpaceOptItem final { if (isString()) { return asString(); } else { - LOG(ERROR) << "collate value illage."; + LOG(ERROR) << "collate value illegal."; return ""; } } @@ -239,7 +239,7 @@ class SpaceOptItem final { if (isString()) { return asString(); } else { - LOG(ERROR) << "group name value illage."; + LOG(ERROR) << "group name value illegal."; return ""; } } @@ -606,10 +606,10 @@ class ShowSessionsSentence final : public Sentence { explicit ShowSessionsSentence(SessionID sessionId) { kind_ = Kind::kShowSessions; sessionId_ = sessionId; - setSeesionId_ = true; + setSessionId_ = true; } - bool isSetSessionID() const { return setSeesionId_; } + bool isSetSessionID() const { return setSessionId_; } SessionID getSessionID() const { return sessionId_; } @@ -617,7 +617,7 @@ class ShowSessionsSentence final : public Sentence { private: SessionID sessionId_{0}; - bool setSeesionId_{false}; + bool setSessionId_{false}; }; class ShowQueriesSentence final : public Sentence { diff --git a/src/parser/MatchSentence.cpp b/src/parser/MatchSentence.cpp index a0fe1de9a35..a6f06fe3c93 100644 --- a/src/parser/MatchSentence.cpp +++ b/src/parser/MatchSentence.cpp @@ -7,6 +7,10 @@ namespace nebula { +std::string MatchStepRange::toString() const { + return folly::stringPrintf("%lu..%lu", min(), max()); +} + std::string MatchClause::toString() const { std::string buf; buf.reserve(256); @@ -107,7 +111,7 @@ std::string MatchEdge::toString() const { buf += "*"; if (range_->min() == range_->max()) { buf += folly::to(range_->min()); - } else if (range_->max() == std::numeric_limits::max()) { + } else if (range_->max() == std::numeric_limits::max()) { if (range_->min() != 1) { buf += folly::to(range_->min()); buf += ".."; diff --git a/src/parser/MatchSentence.h b/src/parser/MatchSentence.h index 923dda6f31d..4390650b164 100644 --- a/src/parser/MatchSentence.h +++ b/src/parser/MatchSentence.h @@ -28,7 +28,7 @@ class MatchEdgeTypeList final { class MatchStepRange final { public: - explicit MatchStepRange(int64_t min, int64_t max = std::numeric_limits::max()) { + explicit MatchStepRange(size_t min = 0, size_t max = std::numeric_limits::max()) { min_ = min; max_ = max; } @@ -37,9 +37,11 @@ class MatchStepRange final { auto max() const { return max_; } + std::string toString() const; + private: - int64_t min_{1}; - int64_t max_{1}; + size_t min_{1}; + size_t max_{1}; }; class MatchEdgeProp final { diff --git a/src/parser/parser.yy b/src/parser/parser.yy index fd9e8d485fe..68a76125b50 100644 --- a/src/parser/parser.yy +++ b/src/parser/parser.yy @@ -387,7 +387,7 @@ static constexpr size_t kCommentLengthLimit = 256; %type opt_if_not_exists %type opt_if_exists -%type opt_with_properites +%type opt_with_properties %left QM COLON %left KW_OR KW_XOR @@ -867,7 +867,7 @@ predicate_expression | KW_EXISTS L_PAREN expression R_PAREN { if ($3->kind() != Expression::Kind::kLabelAttribute && $3->kind() != Expression::Kind::kAttribute && $3->kind() != Expression::Kind::kSubscript) { - throw nebula::GraphParser::syntax_error(@3, "The exists only accept LabelAttribe, Attribute and Subscript"); + throw nebula::GraphParser::syntax_error(@3, "The exists only accept LabelAttribute, Attribute and Subscript"); } $$ = PredicateExpression::make(qctx->objPool(), "exists", "", $3, nullptr); } @@ -1509,7 +1509,7 @@ match_clause delete($3); throw nebula::GraphParser::syntax_error(@3, "Invalid use of aggregating function in this context."); } else { - $$ = new MatchClause($2, $3, false/*optinal*/); + $$ = new MatchClause($2, $3, false/*optional*/); } } | KW_OPTIONAL KW_MATCH match_path where_clause { @@ -1687,16 +1687,36 @@ match_step_range $$ = new MatchStepRange(1); } | STAR legal_integer { - $$ = new MatchStepRange($2, $2); + if ($2 < 0) { + throw nebula::GraphParser::syntax_error(@2, "Expected an unsigned integer."); + } + auto step = static_cast($2); + $$ = new MatchStepRange(step, step); } | STAR DOT_DOT legal_integer { - $$ = new MatchStepRange(1, $3); + if ($3 < 0) { + throw nebula::GraphParser::syntax_error(@3, "Expected an unsigned integer."); + } + auto step = static_cast($3); + $$ = new MatchStepRange(1, step); } | STAR legal_integer DOT_DOT { - $$ = new MatchStepRange($2); + if ($2 < 0) { + throw nebula::GraphParser::syntax_error(@2, "Expected an unsigned integer."); + } + auto step = static_cast($2); + $$ = new MatchStepRange(step); } | STAR legal_integer DOT_DOT legal_integer { - $$ = new MatchStepRange($2, $4); + if ($2 < 0) { + throw nebula::GraphParser::syntax_error(@2, "Expected an unsigned integer."); + } + auto min = static_cast($2); + if ($4 < 0) { + throw nebula::GraphParser::syntax_error(@4, "Expected an unsigned integer."); + } + auto max = static_cast($4); + $$ = new MatchStepRange(min, max); } ; @@ -1922,7 +1942,7 @@ text_search_expression } ; - // TODO : unfiy the text_search_expression into expression in the future + // TODO : unify the text_search_expression into expression in the future // The current version only support independent text_search_expression for lookup_sentence lookup_where_clause : %empty { $$ = nullptr; } @@ -2046,7 +2066,7 @@ fetch_sentence ; find_path_sentence - : KW_FIND KW_ALL KW_PATH opt_with_properites from_clause to_clause over_clause where_clause find_path_upto_clause { + : KW_FIND KW_ALL KW_PATH opt_with_properties from_clause to_clause over_clause where_clause find_path_upto_clause { auto *s = new FindPathSentence(false, $4, false); s->setFrom($5); s->setTo($6); @@ -2055,7 +2075,7 @@ find_path_sentence s->setStep($9); $$ = s; } - | KW_FIND KW_SHORTEST KW_PATH opt_with_properites from_clause to_clause over_clause where_clause find_path_upto_clause { + | KW_FIND KW_SHORTEST KW_PATH opt_with_properties from_clause to_clause over_clause where_clause find_path_upto_clause { auto *s = new FindPathSentence(true, $4, false); s->setFrom($5); s->setTo($6); @@ -2064,7 +2084,7 @@ find_path_sentence s->setStep($9); $$ = s; } - | KW_FIND KW_NOLOOP KW_PATH opt_with_properites from_clause to_clause over_clause where_clause find_path_upto_clause { + | KW_FIND KW_NOLOOP KW_PATH opt_with_properties from_clause to_clause over_clause where_clause find_path_upto_clause { auto *s = new FindPathSentence(false, $4, true); s->setFrom($5); s->setTo($6); @@ -2075,7 +2095,7 @@ find_path_sentence } ; -opt_with_properites +opt_with_properties : %empty { $$ = false; } | KW_WITH KW_PROP { $$ = true; } ; @@ -2133,7 +2153,7 @@ both_in_out_clause | KW_BOTH over_edges { $$ = new BothInOutClause($2, BoundClause::BOTH); } get_subgraph_sentence - : KW_GET KW_SUBGRAPH opt_with_properites step_clause from_clause in_bound_clause out_bound_clause both_in_out_clause yield_clause { + : KW_GET KW_SUBGRAPH opt_with_properties step_clause from_clause in_bound_clause out_bound_clause both_in_out_clause yield_clause { $$ = new GetSubgraphSentence($3, $4, $5, $6, $7, $8, $9); } diff --git a/src/parser/test/ScannerTest.cpp b/src/parser/test/ScannerTest.cpp index d9e7009fdb4..f842233d960 100644 --- a/src/parser/test/ScannerTest.cpp +++ b/src/parser/test/ScannerTest.cpp @@ -107,10 +107,10 @@ TEST(Scanner, Basic) { }; \ GraphScanner lexer; \ lexer.setReadBuffer(input); \ - nebula::GraphParser::semantic_type dumyyylval; \ - nebula::GraphParser::location_type dumyyyloc; \ + nebula::GraphParser::semantic_type dummyyylval; \ + nebula::GraphParser::location_type dummyyyloc; \ try { \ - auto token = lexer.yylex(&dumyyylval, &dumyyyloc); \ + auto token = lexer.yylex(&dummyyylval, &dummyyyloc); \ if (token != 0) { \ return AssertionFailure() << "Lexical error should've " \ << "happened for `" << STR << "'"; \ diff --git a/src/storage/BaseProcessor-inl.h b/src/storage/BaseProcessor-inl.h index af13b402b98..acfb5bc2474 100644 --- a/src/storage/BaseProcessor-inl.h +++ b/src/storage/BaseProcessor-inl.h @@ -166,21 +166,21 @@ StatusOr BaseProcessor::encodeRowVal(const meta::NebulaSchema for (size_t i = 0; i < propNames.size(); i++) { wRet = rowWrite.setValue(propNames[i], props[i]); if (wRet != WriteResult::SUCCEEDED) { - return Status::Error("Add field faild"); + return Status::Error("Add field failed"); } } } else { for (size_t i = 0; i < props.size(); i++) { wRet = rowWrite.setValue(i, props[i]); if (wRet != WriteResult::SUCCEEDED) { - return Status::Error("Add field faild"); + return Status::Error("Add field failed"); } } } wRet = rowWrite.finish(); if (wRet != WriteResult::SUCCEEDED) { - return Status::Error("Add field faild"); + return Status::Error("Add field failed"); } return std::move(rowWrite).moveEncodedStr(); diff --git a/src/storage/CompactionFilter.h b/src/storage/CompactionFilter.h index f035ac3fa6a..6f95e3675fd 100644 --- a/src/storage/CompactionFilter.h +++ b/src/storage/CompactionFilter.h @@ -37,7 +37,7 @@ class StorageCompactionFilter final : public kvstore::KVFilter { return false; } - if (NebulaKeyUtils::isVertex(vIdLen_, key)) { + if (NebulaKeyUtils::isTag(vIdLen_, key)) { return !vertexValid(spaceId, key, val); } else if (NebulaKeyUtils::isEdge(vIdLen_, key)) { return !edgeValid(spaceId, key, val); diff --git a/src/storage/StorageFlags.cpp b/src/storage/StorageFlags.cpp index fc50458fc68..2aa3a35f4bc 100644 --- a/src/storage/StorageFlags.cpp +++ b/src/storage/StorageFlags.cpp @@ -40,7 +40,7 @@ DEFINE_string(reader_handlers_type, "cpu", "Type of reader handlers, options: cp DEFINE_bool(trace_toss, false, "output verbose log of toss"); -DEFINE_int32(max_edge_returned_per_vertex, INT_MAX, "Max edge number returnred searching vertex"); +DEFINE_int32(max_edge_returned_per_vertex, INT_MAX, "Max edge number returned searching vertex"); DEFINE_bool(query_concurrently, false, diff --git a/src/storage/admin/AdminProcessor.h b/src/storage/admin/AdminProcessor.h index 0d3ea444dc0..bd55ef10955 100644 --- a/src/storage/admin/AdminProcessor.h +++ b/src/storage/admin/AdminProcessor.h @@ -87,7 +87,7 @@ class TransLeaderProcessor : public BaseProcessor { onFinished(); return; } else if (leader != HostAddr("", 0)) { - LOG(INFO) << "I am choosen as leader of space " << spaceId << " part " << partId + LOG(INFO) << "I am chosen as leader of space " << spaceId << " part " << partId << " again!"; pushResultCode(nebula::cpp2::ErrorCode::E_TRANSFER_LEADER_FAILED, partId); onFinished(); diff --git a/src/storage/admin/AdminTask.h b/src/storage/admin/AdminTask.h index d434b1a67d0..bbc99df3f1e 100644 --- a/src/storage/admin/AdminTask.h +++ b/src/storage/admin/AdminTask.h @@ -85,9 +85,9 @@ class AdminTask { virtual int getTaskId() { return ctx_.taskId_; } - virtual void setConcurrentReq(int concurrenctReq) { - if (concurrenctReq > 0) { - ctx_.concurrentReq_ = concurrenctReq; + virtual void setConcurrentReq(int concurrentReq) { + if (concurrentReq > 0) { + ctx_.concurrentReq_ = concurrentReq; } } diff --git a/src/storage/admin/AdminTaskManager.cpp b/src/storage/admin/AdminTaskManager.cpp index bc7f92e735b..5e444888d2e 100644 --- a/src/storage/admin/AdminTaskManager.cpp +++ b/src/storage/admin/AdminTaskManager.cpp @@ -19,7 +19,7 @@ namespace nebula { namespace storage { bool AdminTaskManager::init() { - LOG(INFO) << "max concurrenct subtasks: " << FLAGS_max_concurrent_subtasks; + LOG(INFO) << "max concurrent subtasks: " << FLAGS_max_concurrent_subtasks; auto threadFactory = std::make_shared("TaskManager"); pool_ = std::make_unique(FLAGS_max_concurrent_subtasks, threadFactory); bgThread_ = std::make_unique(); diff --git a/src/storage/admin/RebuildIndexTask.cpp b/src/storage/admin/RebuildIndexTask.cpp index c8747374c64..195ee5eaaa0 100644 --- a/src/storage/admin/RebuildIndexTask.cpp +++ b/src/storage/admin/RebuildIndexTask.cpp @@ -19,8 +19,8 @@ RebuildIndexTask::RebuildIndexTask(StorageEnv* env, TaskContext&& ctx) // Rebuild index rate is limited to FLAGS_rebuild_index_part_rate_limit * SubTaskConcurrency. As // for default configuration in a 3 replica cluster, send rate is 512Kb for a partition. From a // global perspective, the leaders are distributed evenly, so both send and recv traffic will be - // 1Mb (512 * 2 peers). Muliplied by the subtasks concurrency, the total send/recv traffic will be - // 10Mb, which is non-trival. + // 1Mb (512 * 2 peers). Multiplied by the subtasks concurrency, the total send/recv traffic will + // be 10Mb, which is non-trival. LOG(INFO) << "Rebuild index task is rate limited to " << FLAGS_rebuild_index_part_rate_limit << " for each subtask by default"; } @@ -31,8 +31,8 @@ ErrorOr> RebuildIndexTask::ge auto parts = *ctx_.parameters_.parts_ref(); IndexItems items; - if (!ctx_.parameters_.task_specfic_paras_ref().has_value() || - (*ctx_.parameters_.task_specfic_paras_ref()).empty()) { + if (!ctx_.parameters_.task_specific_paras_ref().has_value() || + (*ctx_.parameters_.task_specific_paras_ref()).empty()) { auto itemsRet = getIndexes(space_); if (!itemsRet.ok()) { LOG(ERROR) << "Indexes not found"; @@ -41,7 +41,7 @@ ErrorOr> RebuildIndexTask::ge items = std::move(itemsRet).value(); } else { - for (const auto& index : *ctx_.parameters_.task_specfic_paras_ref()) { + for (const auto& index : *ctx_.parameters_.task_specific_paras_ref()) { auto indexID = folly::to(index); auto indexRet = getIndex(space_, indexID); if (!indexRet.ok()) { @@ -78,7 +78,7 @@ nebula::cpp2::ErrorCode RebuildIndexTask::invoke(GraphSpaceID space, PartitionID part, const IndexItems& items) { auto rateLimiter = std::make_unique(); - // TaskMananger will make sure that there won't be cocurrent invoke of a given part + // TaskManager will make sure that there won't be cocurrent invoke of a given part auto result = removeLegacyLogs(space, part); if (result != nebula::cpp2::ErrorCode::SUCCEEDED) { LOG(ERROR) << "Remove legacy logs at part: " << part << " failed"; diff --git a/src/storage/admin/RebuildTagIndexTask.cpp b/src/storage/admin/RebuildTagIndexTask.cpp index bc16b39eb81..4368d707053 100644 --- a/src/storage/admin/RebuildTagIndexTask.cpp +++ b/src/storage/admin/RebuildTagIndexTask.cpp @@ -52,7 +52,7 @@ nebula::cpp2::ErrorCode RebuildTagIndexTask::buildIndexGlobal(GraphSpaceID space auto vidSize = vidSizeRet.value(); std::unique_ptr iter; - auto prefix = NebulaKeyUtils::vertexPrefix(part); + auto prefix = NebulaKeyUtils::tagPrefix(part); auto ret = env_->kvstore_->prefix(space, part, prefix, &iter); if (ret != nebula::cpp2::ErrorCode::SUCCEEDED) { LOG(ERROR) << "Processing Part " << part << " Failed"; diff --git a/src/storage/admin/StatsTask.cpp b/src/storage/admin/StatsTask.cpp index 91774fc8b5b..beeeaed347b 100644 --- a/src/storage/admin/StatsTask.cpp +++ b/src/storage/admin/StatsTask.cpp @@ -94,9 +94,9 @@ nebula::cpp2::ErrorCode StatsTask::genSubTask(GraphSpaceID spaceId, } auto partitionNum = partitionNumRet.value(); - LOG(INFO) << "Start statis task"; + LOG(INFO) << "Start stats task"; CHECK_NOTNULL(env_->kvstore_); - auto vertexPrefix = NebulaKeyUtils::vertexPrefix(part); + auto vertexPrefix = NebulaKeyUtils::tagPrefix(part); std::unique_ptr vertexIter; auto edgePrefix = NebulaKeyUtils::edgePrefix(part); std::unique_ptr edgeIter; @@ -131,7 +131,7 @@ nebula::cpp2::ErrorCode StatsTask::genSubTask(GraphSpaceID spaceId, VertexID lastVertexId = ""; - // Only statis valid vetex data, no multi version + // Only stats valid vertex data, no multi version // For example // Vid tagId // 1 1 @@ -161,7 +161,7 @@ nebula::cpp2::ErrorCode StatsTask::genSubTask(GraphSpaceID spaceId, vertexIter->next(); } - // Only statis valid edge data, no multi version + // Only stats valid edge data, no multi version // For example // src edgetype rank dst // 1 1 1 2 @@ -223,8 +223,8 @@ nebula::cpp2::ErrorCode StatsTask::genSubTask(GraphSpaceID spaceId, statsItem.set_space_vertices(spaceVertices); statsItem.set_space_edges(spaceEdges); - using Correlativiyties = std::vector; - Correlativiyties positiveCorrelativity; + using Correlativities = std::vector; + Correlativities positiveCorrelativity; for (const auto& entry : positiveRelevancy) { nebula::meta::cpp2::Correlativity partProportion; partProportion.set_part_id(entry.first); @@ -233,7 +233,7 @@ nebula::cpp2::ErrorCode StatsTask::genSubTask(GraphSpaceID spaceId, positiveCorrelativity.emplace_back(std::move(partProportion)); } - Correlativiyties negativeCorrelativity; + Correlativities negativeCorrelativity; for (const auto& entry : negativeRelevancy) { nebula::meta::cpp2::Correlativity partProportion; partProportion.set_part_id(entry.first); @@ -252,13 +252,13 @@ nebula::cpp2::ErrorCode StatsTask::genSubTask(GraphSpaceID spaceId, negativeCorrelativity.end(), [&](const auto& l, const auto& r) { return *l.proportion_ref() < *r.proportion_ref(); }); - std::unordered_map positivePartCorrelativiyties; - positivePartCorrelativiyties[part] = positiveCorrelativity; - statsItem.set_positive_part_correlativity(std::move(positivePartCorrelativiyties)); + std::unordered_map positivePartCorrelativities; + positivePartCorrelativities[part] = positiveCorrelativity; + statsItem.set_positive_part_correlativity(std::move(positivePartCorrelativities)); - std::unordered_map negativePartCorrelativiyties; - negativePartCorrelativiyties[part] = negativeCorrelativity; - statsItem.set_negative_part_correlativity(std::move(negativePartCorrelativiyties)); + std::unordered_map negativePartCorrelativities; + negativePartCorrelativities[part] = negativeCorrelativity; + statsItem.set_negative_part_correlativity(std::move(negativePartCorrelativities)); statistics_.emplace(part, std::move(statsItem)); LOG(INFO) << "Stats task finished"; diff --git a/src/storage/exec/AggregateNode.h b/src/storage/exec/AggregateNode.h index 539deeaea2e..bdf1fcba26e 100644 --- a/src/storage/exec/AggregateNode.h +++ b/src/storage/exec/AggregateNode.h @@ -30,7 +30,7 @@ struct PropStat { // some stat of all valid edges of a vertex. It could be used in ScanVertex or // ScanEdge later. The stat is collected during we iterate over edges via // `next`, so if you want to get the final result, be sure to call -// `calculateStat` and then retrieve the reuslt +// `calculateStat` and then retrieve the result template class AggregateNode : public IterateNode { public: diff --git a/src/storage/exec/FilterNode.h b/src/storage/exec/FilterNode.h index 959b66962d6..b70df4d389b 100644 --- a/src/storage/exec/FilterNode.h +++ b/src/storage/exec/FilterNode.h @@ -22,7 +22,7 @@ data, but not both. As for GetNeighbors, it will have filter that involves both tag and edge expression. In that case, FilterNode has a upstream of HashJoinNode, which will -keep popping out edge data. All tage data has been put into ExpressionContext +keep popping out edge data. All tag data has been put into ExpressionContext before FilterNode is doExecuted. By that means, it can check the filter of tag + edge. */ diff --git a/src/storage/exec/HashJoinNode.h b/src/storage/exec/HashJoinNode.h index 3b3dc22ef03..5e6aad1ece1 100644 --- a/src/storage/exec/HashJoinNode.h +++ b/src/storage/exec/HashJoinNode.h @@ -15,7 +15,7 @@ namespace nebula { namespace storage { -// HashJoinNode has input of serveral TagNode and EdgeNode, the EdgeNode is +// HashJoinNode has input of several TagNode and EdgeNode, the EdgeNode is // several SingleEdgeNode of different edge types all edges of a vertex. The // output would be the result of tag, it is a List, each cell save a list of // property values, if tag not found, it will be a empty value. Also it will diff --git a/src/storage/exec/IndexScanNode.h b/src/storage/exec/IndexScanNode.h index fe8838aa4f8..ac600d641fb 100644 --- a/src/storage/exec/IndexScanNode.h +++ b/src/storage/exec/IndexScanNode.h @@ -44,16 +44,16 @@ namespace storage { * Member: * `indexId_` : index_ in this Node to access * `partId_` : part to access.It will be modify while `doExecute` - * `index_` : index defination + * `index_` : index definition * `indexNullable_` : if index contain nullable field or not * `columnHints_` : * `path_` : - * `iter_` : current kvstore iterator.It while be reseted `doExecute` and iterated + * `iter_` : current kvstore iterator.It while be reset `doExecute` and iterated * during `doNext` * `kvstore_` : server kvstore * `requiredColumns_` : row format that `doNext` needs to return * `requiredAndHintColumns_`: columns that `decodeFromBase` needs to decode - * `ttlProps` : ttl properties `needAccesBase_` : if need + * `ttlProps` : ttl properties `needAccessBase_` : if need * `fatalOnBaseNotFound_` : for debug * * Function: @@ -76,13 +76,13 @@ namespace storage { * `Path` not only generate the key to access, but also `qualified` whether the key complies with * the columnhint constraint or not.For example, if there is a truncated string index, we cannot * simply compare bytes to determine whether the current key complies with the columnhints - * constraint, the result of `qulified(bytes)` should be `UNCERTAIN` and `IndexScanNode` will - * access base data then `Path` reconfirm `ColumnHint` constraint by `qulified(RowData)`. In + * constraint, the result of `qualified(bytes)` should be `UNCERTAIN` and `IndexScanNode` will + * access base data then `Path` reconfirm `ColumnHint` constraint by `qualified(RowData)`. In * addition to the above examples, there are other cases to deal with.`Path` and it's derive class * will dynamic different strategy by `ColumnHint`,`IndexItem`,and `Schema`.All strategy will be * added to `QFList_`(QualifiedFunctionList) during `buildKey`, and executed during `qualified`. * - * `Path` whild be reseted when `IndexScanNode` execute on a new part. + * `Path` will be reset when `IndexScanNode` execute on a new part. * * It should be noted that the range generated by `rangepath` is a certain left included and right * excluded interval,like [startKey_, endKey_), although `ColumnHint` may have many different @@ -112,8 +112,8 @@ namespace storage { * * Function: * `make` : construct `PrefixPath` or `RangePath` according to `hints` - * `qualified(StringPiece)` : qulified key by bytes - * `qualified(Map)` : qulified row by value + * `qualified(StringPiece)` : qualified key by bytes + * `qualified(Map)` : qualified row by value * `resetPart` : reset current partitionID and reset `iter_` * `encodeValue` : encode a Value to bytes * @@ -247,7 +247,7 @@ class QualifiedStrategy { * * Args: * `dedupSuffixLength` : If indexed schema is a tag, `dedupSuffixLength` should be vid.len; - * If the indexed schema is an edge, `dedupSuffixLength` shoule be + * If the indexed schema is an edge, `dedupSuffixLength` should be * srcId.len+sizeof(rank)+dstId.len * Return: * When suffix first appears, the function returns `COMPATIBLE`; otherwise, the function returns @@ -286,7 +286,7 @@ class QualifiedStrategy { * `UNCERTAIN`, and (ab)c > aa is COMPATIBLE. * * Args: - * `LEorGE` : It's an assit arg. true means LE and false means GE. + * `LEorGE` : It's an assist arg. true means LE and false means GE. * `val` : Truncated `String` index value,whose length has been define in `IndexItem`. * `keyStartPos` : The position in indexKey where start compare with `val` * diff --git a/src/storage/exec/IndexSelectionNode.h b/src/storage/exec/IndexSelectionNode.h index a134ecf890d..04dd8694638 100644 --- a/src/storage/exec/IndexSelectionNode.h +++ b/src/storage/exec/IndexSelectionNode.h @@ -59,7 +59,7 @@ class IndexSelectionNode : public IndexNode { } Expression *expr_; Map colPos_; - // TODO(hs.zhang): `ExprContext` could be moved out later if we unify the valcano in go/lookup + // TODO(hs.zhang): `ExprContext` could be moved out later if we unify the volcano in go/lookup class ExprContext : public ExpressionContext { public: explicit ExprContext(const Map &colPos) : colPos_(colPos) {} diff --git a/src/storage/exec/IndexVertexScanNode.cpp b/src/storage/exec/IndexVertexScanNode.cpp index 499a4d59d8a..a2a61c42f75 100644 --- a/src/storage/exec/IndexVertexScanNode.cpp +++ b/src/storage/exec/IndexVertexScanNode.cpp @@ -15,9 +15,9 @@ IndexVertexScanNode::IndexVertexScanNode(const IndexVertexScanNode& node) IndexVertexScanNode::IndexVertexScanNode(RuntimeContext* context, IndexID indexId, - const std::vector& clolumnHint, + const std::vector& columnHint, ::nebula::kvstore::KVStore* kvstore) - : IndexScanNode(context, "IndexVertexScanNode", indexId, clolumnHint, kvstore) { + : IndexScanNode(context, "IndexVertexScanNode", indexId, columnHint, kvstore) { getIndex = std::function([this](std::shared_ptr& index) { auto env = this->context_->env(); auto indexMgr = env->indexMan_; @@ -53,10 +53,10 @@ ::nebula::cpp2::ErrorCode IndexVertexScanNode::init(InitContext& ctx) { nebula::cpp2::ErrorCode IndexVertexScanNode::getBaseData(folly::StringPiece key, std::pair& kv) { - kv.first = NebulaKeyUtils::vertexKey(context_->vIdLen(), - partId_, - key.subpiece(key.size() - context_->vIdLen()).toString(), - context_->tagId_); + kv.first = NebulaKeyUtils::tagKey(context_->vIdLen(), + partId_, + key.subpiece(key.size() - context_->vIdLen()).toString(), + context_->tagId_); return kvstore_->get(context_->spaceId(), partId_, kv.first, &kv.second); } diff --git a/src/storage/exec/IndexVertexScanNode.h b/src/storage/exec/IndexVertexScanNode.h index fea56a19adb..48be02e2d1a 100644 --- a/src/storage/exec/IndexVertexScanNode.h +++ b/src/storage/exec/IndexVertexScanNode.h @@ -26,7 +26,7 @@ class IndexVertexScanNode final : public IndexScanNode { IndexVertexScanNode(const IndexVertexScanNode& node); IndexVertexScanNode(RuntimeContext* context, IndexID indexId, - const std::vector& clolumnHint, + const std::vector& columnHint, ::nebula::kvstore::KVStore* kvstore); ::nebula::cpp2::ErrorCode init(InitContext& ctx) override; std::unique_ptr copy() override; diff --git a/src/storage/exec/ScanNode.h b/src/storage/exec/ScanNode.h index 3778eb87804..5af7912f758 100644 --- a/src/storage/exec/ScanNode.h +++ b/src/storage/exec/ScanNode.h @@ -43,7 +43,7 @@ class ScanVertexPropNode : public QueryNode { } std::string start; - std::string prefix = NebulaKeyUtils::vertexPrefix(partId); + std::string prefix = NebulaKeyUtils::tagPrefix(partId); if (cursor.empty()) { start = prefix; } else { diff --git a/src/storage/exec/StoragePlan.h b/src/storage/exec/StoragePlan.h index 181e18c4c5a..0c48daa0dc8 100644 --- a/src/storage/exec/StoragePlan.h +++ b/src/storage/exec/StoragePlan.h @@ -14,11 +14,11 @@ namespace nebula { namespace storage { /* -Origined from folly::FutureDAG, not thread-safe. +Originated from folly::FutureDAG, not thread-safe. The StoragePlan contains a set of RelNode, all you need to do is define a RelNode, add it to plan by calling addNode, which will return the index of the -RelNode in this plan. The denpendencies between different nodes is defined by +RelNode in this plan. The dependencies between different nodes is defined by calling addDependency in RelNode. To run the plan, call the go method, you could get the final result. diff --git a/src/storage/exec/TagNode.h b/src/storage/exec/TagNode.h index d6d597addc8..e2086738518 100644 --- a/src/storage/exec/TagNode.h +++ b/src/storage/exec/TagNode.h @@ -50,7 +50,7 @@ class TagNode final : public IterateNode { VLOG(1) << "partId " << partId << ", vId " << vId << ", tagId " << tagId_ << ", prop size " << props_->size(); - key_ = NebulaKeyUtils::vertexKey(context_->vIdLen(), partId, vId, tagId_); + key_ = NebulaKeyUtils::tagKey(context_->vIdLen(), partId, vId, tagId_); ret = context_->env()->kvstore_->get(context_->spaceId(), partId, key_, &value_); if (ret == nebula::cpp2::ErrorCode::SUCCEEDED) { return doExecute(key_, value_); diff --git a/src/storage/exec/UpdateNode.h b/src/storage/exec/UpdateNode.h index e9ef3c9d072..0b6e3abe36d 100644 --- a/src/storage/exec/UpdateNode.h +++ b/src/storage/exec/UpdateNode.h @@ -269,7 +269,7 @@ class UpdateTagNode : public UpdateNode { expCtx_->setTagProp(tagName_, p.first, p.second); } - key_ = NebulaKeyUtils::vertexKey(context_->vIdLen(), partId, vId, tagId_); + key_ = NebulaKeyUtils::tagKey(context_->vIdLen(), partId, vId, tagId_); rowWriter_ = std::make_unique(schema_); return nebula::cpp2::ErrorCode::SUCCEEDED; @@ -331,7 +331,7 @@ class UpdateTagNode : public UpdateNode { for (auto& e : props_) { auto wRet = rowWriter_->setValue(e.first, e.second); if (wRet != WriteResult::SUCCEEDED) { - LOG(ERROR) << "Add field faild "; + LOG(ERROR) << "Add field failed "; return folly::none; } } @@ -340,7 +340,7 @@ class UpdateTagNode : public UpdateNode { auto wRet = rowWriter_->finish(); if (wRet != WriteResult::SUCCEEDED) { - LOG(ERROR) << "Add field faild "; + LOG(ERROR) << "Add field failed "; return folly::none; } @@ -655,7 +655,7 @@ class UpdateEdgeNode : public UpdateNode { for (auto& e : props_) { auto wRet = rowWriter_->setValue(e.first, e.second); if (wRet != WriteResult::SUCCEEDED) { - VLOG(1) << "Add field faild "; + VLOG(1) << "Add field failed "; return folly::none; } } @@ -664,7 +664,7 @@ class UpdateEdgeNode : public UpdateNode { auto wRet = rowWriter_->finish(); if (wRet != WriteResult::SUCCEEDED) { - VLOG(1) << "Add field faild "; + VLOG(1) << "Add field failed "; return folly::none; } diff --git a/src/storage/mutate/AddVerticesProcessor.cpp b/src/storage/mutate/AddVerticesProcessor.cpp index cdd897e8373..2396014d841 100644 --- a/src/storage/mutate/AddVerticesProcessor.cpp +++ b/src/storage/mutate/AddVerticesProcessor.cpp @@ -90,7 +90,7 @@ void AddVerticesProcessor::doProcess(const cpp2::AddVerticesRequest& req) { break; } - auto key = NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vid, tagId); + auto key = NebulaKeyUtils::tagKey(spaceVidLen_, partId, vid, tagId); if (ifNotExists_) { if (!visited.emplace(key).second) { continue; @@ -142,7 +142,7 @@ void AddVerticesProcessor::doProcessWithIndex(const cpp2::AddVerticesRequest& re dummyLock.reserve(vertices.size()); auto code = nebula::cpp2::ErrorCode::SUCCEEDED; - // cache vertexKey + // cache tagKey std::unordered_set visited; visited.reserve(vertices.size()); for (auto& vertex : vertices) { @@ -176,7 +176,7 @@ void AddVerticesProcessor::doProcessWithIndex(const cpp2::AddVerticesRequest& re break; } - auto key = NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vid, tagId); + auto key = NebulaKeyUtils::tagKey(spaceVidLen_, partId, vid, tagId); if (ifNotExists_ && !visited.emplace(key).second) { continue; } @@ -307,7 +307,7 @@ void AddVerticesProcessor::doProcessWithIndex(const cpp2::AddVerticesRequest& re ErrorOr AddVerticesProcessor::findOldValue( PartitionID partId, const VertexID& vId, TagID tagId) { - auto key = NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vId, tagId); + auto key = NebulaKeyUtils::tagKey(spaceVidLen_, partId, vId, tagId); std::string val; auto ret = env_->kvstore_->get(spaceId_, partId, key, &val); if (ret == nebula::cpp2::ErrorCode::SUCCEEDED) { diff --git a/src/storage/mutate/DeleteTagsProcessor.cpp b/src/storage/mutate/DeleteTagsProcessor.cpp index 5aae7132f7d..af414c55ba4 100644 --- a/src/storage/mutate/DeleteTagsProcessor.cpp +++ b/src/storage/mutate/DeleteTagsProcessor.cpp @@ -55,7 +55,7 @@ void DeleteTagsProcessor::process(const cpp2::DeleteTagsRequest& req) { for (const auto& entry : delTags) { const auto& vId = entry.get_id().getStr(); for (const auto& tagId : entry.get_tags()) { - auto key = NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vId, tagId); + auto key = NebulaKeyUtils::tagKey(spaceVidLen_, partId, vId, tagId); keys.emplace_back(std::move(key)); } } @@ -94,7 +94,7 @@ ErrorOr DeleteTagsProcessor::deleteTags( for (const auto& entry : delTags) { const auto& vId = entry.get_id().getStr(); for (const auto& tagId : entry.get_tags()) { - auto key = NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vId, tagId); + auto key = NebulaKeyUtils::tagKey(spaceVidLen_, partId, vId, tagId); auto tup = std::make_tuple(spaceId_, partId, tagId, vId); // ignore if there are duplicate delete if (std::find(lockedKeys.begin(), lockedKeys.end(), tup) != lockedKeys.end()) { diff --git a/src/storage/mutate/DeleteVerticesProcessor.cpp b/src/storage/mutate/DeleteVerticesProcessor.cpp index eb37ff8ce99..e9a6bae1840 100644 --- a/src/storage/mutate/DeleteVerticesProcessor.cpp +++ b/src/storage/mutate/DeleteVerticesProcessor.cpp @@ -62,7 +62,7 @@ void DeleteVerticesProcessor::process(const cpp2::DeleteVerticesRequest& req) { break; } - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen_, partId, vid.getStr()); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vid.getStr()); std::unique_ptr iter; code = env_->kvstore_->prefix(spaceId_, partId, prefix, &iter); if (code != nebula::cpp2::ErrorCode::SUCCEEDED) { @@ -112,7 +112,7 @@ ErrorOr DeleteVerticesProcessor::deleteVer target.reserve(vertices.size()); std::unique_ptr batchHolder = std::make_unique(); for (auto& vertex : vertices) { - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen_, partId, vertex.getStr()); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vertex.getStr()); std::unique_ptr iter; auto ret = env_->kvstore_->prefix(spaceId_, partId, prefix, &iter); if (ret != nebula::cpp2::ErrorCode::SUCCEEDED) { diff --git a/src/storage/query/GetPropProcessor.cpp b/src/storage/query/GetPropProcessor.cpp index 3d57cd72d60..0e48f792278 100644 --- a/src/storage/query/GetPropProcessor.cpp +++ b/src/storage/query/GetPropProcessor.cpp @@ -259,7 +259,7 @@ nebula::cpp2::ErrorCode GetPropProcessor::checkAndBuildContexts(const cpp2::GetP } nebula::cpp2::ErrorCode GetPropProcessor::buildTagContext(const cpp2::GetPropRequest& req) { - // req.vertex_props_ref().has_value() checked in methon checkRequest + // req.vertex_props_ref().has_value() checked in method checkRequest auto returnProps = (*req.vertex_props_ref()).empty() ? buildAllTagProps() : *req.vertex_props_ref(); auto ret = handleVertexProps(returnProps); @@ -272,7 +272,7 @@ nebula::cpp2::ErrorCode GetPropProcessor::buildTagContext(const cpp2::GetPropReq } nebula::cpp2::ErrorCode GetPropProcessor::buildEdgeContext(const cpp2::GetPropRequest& req) { - // req.edge_props_ref().has_value() checked in methon checkRequest + // req.edge_props_ref().has_value() checked in method checkRequest auto returnProps = (*req.edge_props_ref()).empty() ? buildAllEdgeProps(cpp2::EdgeDirection::BOTH) : *req.edge_props_ref(); auto ret = handleEdgeProps(returnProps); diff --git a/src/storage/query/QueryBaseProcessor.h b/src/storage/query/QueryBaseProcessor.h index bf1765ebfa1..3f75b0c5335 100644 --- a/src/storage/query/QueryBaseProcessor.h +++ b/src/storage/query/QueryBaseProcessor.h @@ -96,7 +96,7 @@ struct PropContext { struct TagContext { std::vector>> propContexts_; - // indicates whether TagID is in propContxts_ + // indicates whether TagID is in propContexts_ std::unordered_map indexMap_; // tagId -> tagName std::unordered_map tagNames_; @@ -110,7 +110,7 @@ struct TagContext { struct EdgeContext { // propContexts_, indexMap_, edgeNames_ will contain both +/- edges std::vector>> propContexts_; - // indicates whether EdgeType is in propContxts_ + // indicates whether EdgeType is in propContexts_ std::unordered_map indexMap_; // EdgeType -> edgeName std::unordered_map edgeNames_; diff --git a/src/storage/test/AddAndUpdateVertexAndEdgeBenchmark.cpp b/src/storage/test/AddAndUpdateVertexAndEdgeBenchmark.cpp index d5cd087c480..cd42c365932 100644 --- a/src/storage/test/AddAndUpdateVertexAndEdgeBenchmark.cpp +++ b/src/storage/test/AddAndUpdateVertexAndEdgeBenchmark.cpp @@ -131,7 +131,7 @@ bool mockVertexData(storage::StorageEnv* ev, int32_t totalParts, int32_t vidLen, std::atomic count(1); std::vector data; - auto key = NebulaKeyUtils::vertexKey(vidLen, pId, vertex.vId_, vertex.tId_); + auto key = NebulaKeyUtils::tagKey(vidLen, pId, vertex.vId_, vertex.tId_); auto schema = ev->schemaMan_->getTagSchema(spaceId, vertex.tId_); if (!schema) { LOG(ERROR) << "Invalid tagId " << vertex.tId_; @@ -231,22 +231,22 @@ void setUp(storage::StorageEnv* ev) { // v2 data if (!mockVertexData(ev, parts, spaceVidLen, true)) { - LOG(ERROR) << "Mock data faild"; + LOG(ERROR) << "Mock data failed"; return; } // v1 data if (!mockVertexData(ev, parts, spaceVidLen, false)) { - LOG(ERROR) << "Mock data faild"; + LOG(ERROR) << "Mock data failed"; return; } // v2 data if (!mockEdgeData(ev, parts, spaceVidLen, true)) { - LOG(ERROR) << "Mock data faild"; + LOG(ERROR) << "Mock data failed"; return; } // v1 data if (!mockEdgeData(ev, parts, spaceVidLen, false)) { - LOG(ERROR) << "Mock data faild"; + LOG(ERROR) << "Mock data failed"; return; } } @@ -438,7 +438,7 @@ void insertVertex(int32_t iters) { processor->process(req); auto resp = std::move(f).get(); if (!resp.result.failed_parts.empty()) { - LOG(ERROR) << "Add faild"; + LOG(ERROR) << "Add failed"; return; } } @@ -455,7 +455,7 @@ void insertEdge(int32_t iters) { processor->process(req); auto resp = std::move(f).get(); if (!resp.result.failed_parts.empty()) { - LOG(ERROR) << "Add faild"; + LOG(ERROR) << "Add failed"; return; } } @@ -473,7 +473,7 @@ void updateVertex(int32_t iters, bool isVersion2) { processor->process(req); auto resp = std::move(f).get(); if (!resp.result.failed_parts.empty()) { - LOG(ERROR) << "update faild"; + LOG(ERROR) << "update failed"; return; } } @@ -491,7 +491,7 @@ void updateEdge(int32_t iters, bool isVersion2) { auto resp = std::move(f).get(); if (!resp.result.failed_parts.empty()) { - LOG(ERROR) << "update faild"; + LOG(ERROR) << "update failed"; return; } } diff --git a/src/storage/test/AdminTaskManagerTest.cpp b/src/storage/test/AdminTaskManagerTest.cpp index 6864e8a7f09..deebf61c440 100644 --- a/src/storage/test/AdminTaskManagerTest.cpp +++ b/src/storage/test/AdminTaskManagerTest.cpp @@ -753,8 +753,8 @@ TEST(TaskManagerTest, cancel_a_task_while_some_sub_task_running) { folly::Promise task1_p; folly::Future task1_f = task1_p.getFuture(); - folly::Promise cancle_p; - folly::Future cancel = cancle_p.getFuture(); + folly::Promise cancel_p; + folly::Future cancel = cancel_p.getFuture(); folly::Promise subtask_run_p; folly::Future subtask_run_f = subtask_run_p.getFuture(); @@ -785,7 +785,7 @@ TEST(TaskManagerTest, cancel_a_task_while_some_sub_task_running) { LOG(INFO) << "before taskMgr->cancelTask(1);"; taskMgr->cancelTask(jobId); LOG(INFO) << "after taskMgr->cancelTask(1);"; - cancle_p.setValue(0); + cancel_p.setValue(0); task1_f.wait(); diff --git a/src/storage/test/CMakeLists.txt b/src/storage/test/CMakeLists.txt index c664696de53..ceb3809be17 100644 --- a/src/storage/test/CMakeLists.txt +++ b/src/storage/test/CMakeLists.txt @@ -18,6 +18,7 @@ set(storage_test_deps $ $ $ + $ $ $ $ @@ -85,7 +86,7 @@ nebula_add_test( nebula_add_test( NAME - statis_task_test + stats_task_test SOURCES StatsTaskTest.cpp OBJECTS diff --git a/src/storage/test/CompactionTest.cpp b/src/storage/test/CompactionTest.cpp index c1345915513..7c4f8cf9079 100644 --- a/src/storage/test/CompactionTest.cpp +++ b/src/storage/test/CompactionTest.cpp @@ -21,7 +21,7 @@ namespace nebula { namespace storage { -// statis tag record count, can distinguish multiple versions +// stats tag record count, can distinguish multiple versions void checkTagVertexData(int32_t spaceVidLen, GraphSpaceID spaceId, TagID tagId, @@ -35,7 +35,7 @@ void checkTagVertexData(int32_t spaceVidLen, VertexID lastVertexId = ""; for (int part = 1; part <= parts; part++) { - auto prefix = NebulaKeyUtils::vertexPrefix(part); + auto prefix = NebulaKeyUtils::tagPrefix(part); auto ret = env->kvstore_->prefix(spaceId, part, prefix, &iter); ASSERT_EQ(ret, nebula::cpp2::ErrorCode::SUCCEEDED); @@ -62,7 +62,7 @@ void checkTagVertexData(int32_t spaceVidLen, ASSERT_EQ(expectNum, totalCount); } -// statis edge record count, can distinguish multiple versions +// stats edge record count, can distinguish multiple versions void checkEdgeData(int32_t spaceVidLen, GraphSpaceID spaceId, EdgeType type, @@ -112,7 +112,7 @@ void checkEdgeData(int32_t spaceVidLen, ASSERT_EQ(expectNum, totalCount); } -// statis index record count +// stats index record count void checkIndexData( GraphSpaceID spaceId, IndexID indexId, int parts, StorageEnv* env, int expectNum) { int totalCount = 0; diff --git a/src/storage/test/GetNeighborsBenchmark.cpp b/src/storage/test/GetNeighborsBenchmark.cpp index ac2157984cc..c7a8e96ab55 100644 --- a/src/storage/test/GetNeighborsBenchmark.cpp +++ b/src/storage/test/GetNeighborsBenchmark.cpp @@ -250,7 +250,7 @@ void prefix(int32_t iters, { // read tags std::unique_ptr iter; - auto prefix = nebula::NebulaKeyUtils::vertexPrefix(vIdLen, partId, vId, player); + auto prefix = nebula::NebulaKeyUtils::tagKey(vIdLen, partId, vId, player); auto code = env->kvstore_->prefix(spaceId, partId, prefix, &iter); ASSERT_EQ(code, nebula::cpp2::ErrorCode::SUCCEEDED); CHECK(iter->valid()); @@ -348,7 +348,7 @@ BENCHMARK_RELATIVE(OneVertexFiveProperty, iters) { BENCHMARK_RELATIVE(OneVertexOnePropertyOnlyEdgeNode, iters) { goEdgeNode(iters, {"Tim Duncan"}, {"name"}, {"teamName"}); } -BENCHMARK_RELATIVE(OneVertexOneProperyOnlyKV, iters) { +BENCHMARK_RELATIVE(OneVertexOnePropertyOnlyKV, iters) { prefix(iters, {"Tim Duncan"}, {"name"}, {"teamName"}); } @@ -456,7 +456,7 @@ BENCHMARK_RELATIVE(TenVertexOnePropertyOnlyEdgeNode, iters) { {"name"}, {"teamName"}); } -BENCHMARK_RELATIVE(TenVertexOneProperyOnlyKV, iters) { +BENCHMARK_RELATIVE(TenVertexOnePropertyOnlyKV, iters) { prefix(iters, {"Tim Duncan", "Kobe Bryant", @@ -504,7 +504,7 @@ OneVertexOnlyId 119.10% 374.96us 2.67K OneVertexThreeProperty 59.50% 750.53us 1.33K OneVertexFiveProperty 46.25% 965.55us 1.04K OneVertexOnePropertyOnlyEdgeNode 113.92% 392.01us 2.55K -OneVertexOneProperyOnlyKV 113.08% 394.93us 2.53K +OneVertexOnePropertyOnlyKV 113.08% 394.93us 2.53K ---------------------------------------------------------------------------- NoFilter 444.84us 2.25K OneFilterNonePass 106.16% 419.01us 2.39K @@ -521,6 +521,6 @@ TenVertexOnlyId 119.68% 3.68ms 271.76 TenVertexThreeProperty 59.25% 7.43ms 134.53 TenVertexFiveProperty 45.67% 9.64ms 103.69 TenVertexOnePropertyOnlyEdgeNode 109.45% 4.02ms 248.53 -TenVertexOneProperyOnlyKV 109.23% 4.03ms 248.03 +TenVertexOnePropertyOnlyKV 109.23% 4.03ms 248.03 ============================================================================ */ diff --git a/src/storage/test/GetPropTest.cpp b/src/storage/test/GetPropTest.cpp index 59d3bb6e442..1ed42d03a1f 100644 --- a/src/storage/test/GetPropTest.cpp +++ b/src/storage/test/GetPropTest.cpp @@ -668,7 +668,7 @@ TEST(QueryVertexPropsTest, PrefixBloomFilterTest) { for (const auto& vId : vertices) { PartitionID partId = (hash(vId) % totalParts) + 1; std::unique_ptr iter; - auto prefix = NebulaKeyUtils::vertexPrefix(vIdLen, partId, vId, player); + auto prefix = NebulaKeyUtils::tagPrefix(vIdLen, partId, vId, player); auto code = env->kvstore_->prefix(spaceId, partId, prefix, &iter); ASSERT_EQ(code, nebula::cpp2::ErrorCode::SUCCEEDED); } diff --git a/src/storage/test/IndexScanLimitTest.cpp b/src/storage/test/IndexScanLimitTest.cpp index bb57aef7ff0..83e678c0d4c 100644 --- a/src/storage/test/IndexScanLimitTest.cpp +++ b/src/storage/test/IndexScanLimitTest.cpp @@ -118,9 +118,9 @@ class IndexScanLimitTest : public ::testing::Test { std::string val = vid % 2 == 0 ? val1 : val2; auto vertex = folly::to(vid); auto edgeKey = NebulaKeyUtils::edgeKey(vertexLen, pId, vertex, edgeType, 0, vertex); - auto vertexKey = NebulaKeyUtils::vertexKey(vertexLen, pId, vertex, tagId); + auto tagKey = NebulaKeyUtils::tagKey(vertexLen, pId, vertex, tagId); data.emplace_back(std::move(edgeKey), val); - data.emplace_back(std::move(vertexKey), std::move(val)); + data.emplace_back(std::move(tagKey), std::move(val)); if (indexMan_ != nullptr) { if (indexMan_->getTagIndex(spaceId, tagIndex).ok()) { auto vertexIndexKeys = diff --git a/src/storage/test/IndexTest.cpp b/src/storage/test/IndexTest.cpp index 6c4e34ad122..2b269da938f 100644 --- a/src/storage/test/IndexTest.cpp +++ b/src/storage/test/IndexTest.cpp @@ -152,7 +152,7 @@ class IndexScanTest : public ::testing::Test { std::vector> indices) { std::vector> ret(indices.size() + 1); for (size_t i = 0; i < rows.size(); i++) { - auto key = NebulaKeyUtils::vertexKey(8, 0, std::to_string(i), tagId); + auto key = NebulaKeyUtils::tagKey(8, 0, std::to_string(i), tagId); RowWriterV2 writer(schema.get()); for (size_t j = 0; j < rows[i].size(); j++) { writer.setValue(j, rows[i][j]); diff --git a/src/storage/test/IndexWithTTLTest.cpp b/src/storage/test/IndexWithTTLTest.cpp index 0d61c3248de..a42a2392fcc 100644 --- a/src/storage/test/IndexWithTTLTest.cpp +++ b/src/storage/test/IndexWithTTLTest.cpp @@ -164,7 +164,7 @@ TEST(IndexWithTTLTest, AddVerticesIndexWithTTL) { LOG(INFO) << "Check insert data..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -184,7 +184,7 @@ TEST(IndexWithTTLTest, AddVerticesIndexWithTTL) { LOG(INFO) << "Check data after compaction ..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(0, retNum); } @@ -258,7 +258,7 @@ TEST(IndexWithTTLTest, UpdateVerticesIndexWithTTL) { LOG(INFO) << "Check insert data..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -302,7 +302,7 @@ TEST(IndexWithTTLTest, UpdateVerticesIndexWithTTL) { LOG(INFO) << "Check data after update ..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -405,7 +405,7 @@ TEST(IndexWithTTLTest, RebuildTagIndexWithTTL) { LOG(INFO) << "Check insert data..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -425,7 +425,7 @@ TEST(IndexWithTTLTest, RebuildTagIndexWithTTL) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(parts); - parameter.set_task_specfic_paras({"2021002"}); + parameter.set_task_specific_paras({"2021002"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_TAG_INDEX); @@ -448,7 +448,7 @@ TEST(IndexWithTTLTest, RebuildTagIndexWithTTL) { LOG(INFO) << "Check data after rebuild ..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -494,7 +494,7 @@ TEST(IndexWithTTLTest, RebuildEdgeIndexWithTTL) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(parts); - parameter.set_task_specfic_paras({"2021002"}); + parameter.set_task_specific_paras({"2021002"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_EDGE_INDEX); @@ -543,7 +543,7 @@ TEST(IndexWithTTLTest, RebuildTagIndexWithTTLExpired) { LOG(INFO) << "Check insert data..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -565,7 +565,7 @@ TEST(IndexWithTTLTest, RebuildTagIndexWithTTLExpired) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(parts); - parameter.set_task_specfic_paras({"2021002"}); + parameter.set_task_specific_paras({"2021002"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_TAG_INDEX); @@ -588,7 +588,7 @@ TEST(IndexWithTTLTest, RebuildTagIndexWithTTLExpired) { LOG(INFO) << "Check data after rebuild ..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -636,7 +636,7 @@ TEST(IndexWithTTLTest, RebuildEdgeIndexWithTTLExpired) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(parts); - parameter.set_task_specfic_paras({"2021002"}); + parameter.set_task_specific_paras({"2021002"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_EDGE_INDEX); diff --git a/src/storage/test/IndexWriteTest.cpp b/src/storage/test/IndexWriteTest.cpp index 1aec5beb400..91f30a0f53d 100644 --- a/src/storage/test/IndexWriteTest.cpp +++ b/src/storage/test/IndexWriteTest.cpp @@ -91,7 +91,7 @@ TEST(IndexTest, SimpleVerticesTest) { LOG(INFO) << "Check insert data..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); + auto prefix = NebulaKeyUtils::tagPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -120,7 +120,7 @@ TEST(IndexTest, SimpleVerticesTest) { LOG(INFO) << "Check delete data..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); + auto prefix = NebulaKeyUtils::tagPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(0, retNum); } @@ -286,7 +286,7 @@ TEST(IndexTest, VerticesValueTest) { LOG(INFO) << "Check insert data..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); + auto prefix = NebulaKeyUtils::tagPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); auto retNum = verifyResultNum(1, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -398,7 +398,7 @@ TEST(IndexTest, AlterTagIndexTest) { LOG(INFO) << "Check insert data..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); + auto prefix = NebulaKeyUtils::tagPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); auto retNum = verifyResultNum(spaceId, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } @@ -460,7 +460,7 @@ TEST(IndexTest, AlterTagIndexTest) { LOG(INFO) << "Check insert data..."; for (auto partId = 1; partId <= 6; partId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); + auto prefix = NebulaKeyUtils::tagPrefix(vIdLen, partId, convertVertexId(vIdLen, partId)); auto retNum = verifyResultNum(spaceId, partId, prefix, env->kvstore_); EXPECT_EQ(1, retNum); } diff --git a/src/storage/test/KVClientTest.cpp b/src/storage/test/KVClientTest.cpp index fc8b2e86441..7249997686f 100644 --- a/src/storage/test/KVClientTest.cpp +++ b/src/storage/test/KVClientTest.cpp @@ -33,7 +33,7 @@ void checkResult(StorageRpcResponse& resp, size_t TEST(KVClientTest, SimpleTest) { GraphSpaceID spaceId = 1; fs::TempDir metaPath("/tmp/KVTest.meta.XXXXXX"); - fs::TempDir stoagePath("/tmp/KVTest.stoage.XXXXXX"); + fs::TempDir storagePath("/tmp/KVTest.storage.XXXXXX"); mock::MockCluster cluster; std::string storageName{"127.0.0.1"}; auto storagePort = network::NetworkUtils::getAvailablePort(); @@ -44,7 +44,7 @@ TEST(KVClientTest, SimpleTest) { options.localHost_ = storageAddr; options.role_ = meta::cpp2::HostRole::STORAGE; cluster.initMetaClient(options); - cluster.startStorage(storageAddr, stoagePath.path(), true); + cluster.startStorage(storageAddr, storagePath.path(), true); auto client = cluster.initGeneralStorageClient(); // kv interface test diff --git a/src/storage/test/LookupIndexTest.cpp b/src/storage/test/LookupIndexTest.cpp index 2c883faddff..2e750da42c2 100644 --- a/src/storage/test/LookupIndexTest.cpp +++ b/src/storage/test/LookupIndexTest.cpp @@ -64,7 +64,7 @@ TEST_P(LookupIndexTest, LookupIndexTestV1) { RowWriterV1 writer(schemaV1.get()); writer << true << 1L << 1.1F << 1.1F << "row1"; writer.encode(); - auto key = NebulaKeyUtils::vertexKey(vIdLen.value(), 1, vId1, 3); + auto key = NebulaKeyUtils::tagKey(vIdLen.value(), 1, vId1, 3); keyValues.emplace_back(std::move(key), writer.encode()); // setup V2 row @@ -85,7 +85,7 @@ TEST_P(LookupIndexTest, LookupIndexTestV1) { writer2.setValue("col_date", date); writer2.setValue("col_datetime", dt); writer2.finish(); - key = NebulaKeyUtils::vertexKey(vIdLen.value(), 1, vId2, 3); + key = NebulaKeyUtils::tagKey(vIdLen.value(), 1, vId2, 3); keyValues.emplace_back(std::move(key), writer2.moveEncodedStr()); // setup index key @@ -2104,7 +2104,7 @@ TEST_P(LookupIndexTest, NullablePropertyTest) { req.set_parts({1, 2, 3, 4, 5, 6}); req.set_return_columns({kVid}); - // bool range scan will be forbiden in query engine, so only test preix for + // bool range scan will be forbidden in query engine, so only test prefix for // bool { LOG(INFO) << "lookup on tag where tag.col_bool == true"; diff --git a/src/storage/test/MemoryLockBenchmark.cpp b/src/storage/test/MemoryLockBenchmark.cpp index ac1aaf6f2b6..cc33755577d 100644 --- a/src/storage/test/MemoryLockBenchmark.cpp +++ b/src/storage/test/MemoryLockBenchmark.cpp @@ -36,7 +36,7 @@ void forString(StringLock* lock, int64_t spaceId) noexcept { size_t vIdLen = 32; for (int32_t j = 0; j < FLAGS_num_batch; j++) { toLock.emplace_back(folly::to(spaceId) + - NebulaKeyUtils::vertexKey(vIdLen, j, folly::to(j), j)); + NebulaKeyUtils::tagKey(vIdLen, j, folly::to(j), j)); } nebula::MemoryLockGuard lg(lock, std::move(toLock)); } diff --git a/src/storage/test/PrefixBloomFilterBenchmark.cpp b/src/storage/test/PrefixBloomFilterBenchmark.cpp index 7140fbde060..f4f6750cccf 100644 --- a/src/storage/test/PrefixBloomFilterBenchmark.cpp +++ b/src/storage/test/PrefixBloomFilterBenchmark.cpp @@ -28,7 +28,7 @@ void mockData(StorageEnv* env, int32_t partCount) { vertexId < (partId + 1) * FLAGS_vertex_per_part; vertexId++) { for (TagID tagId = 3001; tagId < 3010; tagId++) { - auto key = NebulaKeyUtils::vertexKey(vIdLen, partId, std::to_string(vertexId), tagId); + auto key = NebulaKeyUtils::tagKey(vIdLen, partId, std::to_string(vertexId), tagId); auto val = folly::stringPrintf("%d_%d", vertexId, tagId); data.emplace_back(std::move(key), std::move(val)); } @@ -53,7 +53,7 @@ void testPrefixSeek(StorageEnv* env, int32_t partCount, int32_t iters) { for (int32_t vertexId = partId * FLAGS_vertex_per_part; vertexId < (partId + 1) * FLAGS_vertex_per_part; vertexId++) { - auto prefix = NebulaKeyUtils::vertexPrefix(vIdLen, partId, std::to_string(vertexId)); + auto prefix = NebulaKeyUtils::tagPrefix(vIdLen, partId, std::to_string(vertexId)); std::unique_ptr iter; auto code = env->kvstore_->prefix(spaceId, partId, prefix, &iter); ASSERT_EQ(code, nebula::cpp2::ErrorCode::SUCCEEDED); diff --git a/src/storage/test/QueryStatsTest.cpp b/src/storage/test/QueryStatsTest.cpp index 04d26977fbd..b8cd99ba942 100644 --- a/src/storage/test/QueryStatsTest.cpp +++ b/src/storage/test/QueryStatsTest.cpp @@ -21,7 +21,7 @@ void mockData(kvstore::KVStore* kv) { std::vector data; for (int32_t vertexId = partId * 10; vertexId < (partId + 1) * 10; vertexId++) { for (int32_t tagId = 3001; tagId < 3010; tagId++) { - auto key = NebulaKeyUtils::vertexKey(partId, vertexId, tagId, 0); + auto key = NebulaKeyUtils::tagKey(partId, vertexId, tagId, 0); auto val = TestUtils::setupEncode(3, 6); data.emplace_back(std::move(key), std::move(val)); } diff --git a/src/storage/test/QueryTestUtils.h b/src/storage/test/QueryTestUtils.h index 24556c2e1fd..05b2371e69d 100644 --- a/src/storage/test/QueryTestUtils.h +++ b/src/storage/test/QueryTestUtils.h @@ -45,7 +45,7 @@ class QueryTestUtils { for (const auto& vertex : vertices) { PartitionID partId = (hash(vertex.vId_) % totalParts) + 1; TagID tagId = vertex.tId_; - auto key = NebulaKeyUtils::vertexKey(spaceVidLen, partId, vertex.vId_, tagId); + auto key = NebulaKeyUtils::tagKey(spaceVidLen, partId, vertex.vId_, tagId); auto schema = env->schemaMan_->getTagSchema(spaceId, tagId); if (!schema) { LOG(ERROR) << "Invalid tagId " << tagId; @@ -779,7 +779,7 @@ class QueryTestUtils { if (cols.size() < 2) { LOG(FATAL) << "Invalid column name"; } - // cols[1] is the tagName, which can be transfromed to entryId + // cols[1] is the tagName, which can be transformed to entryId auto entryId = folly::to(cols[1]); auto props = findExpectProps(entryId, tags, edges); switch (entryId) { @@ -877,7 +877,7 @@ class QueryTestUtils { return teammate.player1_ == player2 && teammate.player2_ == player1; }); if (iter == mock::MockData::teammates_.end()) { - LOG(FATAL) << "Can't find speicied teammate"; + LOG(FATAL) << "Can't find specified teammate"; } return *iter; } diff --git a/src/storage/test/RebuildIndexTest.cpp b/src/storage/test/RebuildIndexTest.cpp index 8661811ea92..4dc34c715ec 100644 --- a/src/storage/test/RebuildIndexTest.cpp +++ b/src/storage/test/RebuildIndexTest.cpp @@ -75,7 +75,7 @@ TEST_F(RebuildIndexTest, RebuildTagIndexCheckALLData) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(parts); - parameter.set_task_specfic_paras({"4", "5"}); + parameter.set_task_specific_paras({"4", "5"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_TAG_INDEX); @@ -101,7 +101,7 @@ TEST_F(RebuildIndexTest, RebuildTagIndexCheckALLData) { EXPECT_LT(0, vidSize); int dataNum = 0; for (auto part : parts) { - auto prefix = NebulaKeyUtils::vertexPrefix(part); + auto prefix = NebulaKeyUtils::tagPrefix(part); std::unique_ptr iter; auto ret = RebuildIndexTest::env_->kvstore_->prefix(1, part, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -162,7 +162,7 @@ TEST_F(RebuildIndexTest, RebuildEdgeIndexCheckALLData) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(parts); - parameter.set_task_specfic_paras({"103", "104"}); + parameter.set_task_specific_paras({"103", "104"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_EDGE_INDEX); @@ -259,7 +259,7 @@ TEST_F(RebuildIndexTest, RebuildTagIndexWithDelete) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(std::move(parts)); - parameter.set_task_specfic_paras({"4", "5"}); + parameter.set_task_specific_paras({"4", "5"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_TAG_INDEX); @@ -320,7 +320,7 @@ TEST_F(RebuildIndexTest, RebuildTagIndexWithAppend) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(std::move(parts)); - parameter.set_task_specfic_paras({"4", "5"}); + parameter.set_task_specific_paras({"4", "5"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_TAG_INDEX); @@ -370,7 +370,7 @@ TEST_F(RebuildIndexTest, RebuildTagIndex) { request.set_cmd(meta::cpp2::AdminCmd::REBUILD_TAG_INDEX); request.set_job_id(++gJobId); request.set_task_id(13); - parameter.set_task_specfic_paras({"4", "5"}); + parameter.set_task_specific_paras({"4", "5"}); request.set_para(std::move(parameter)); auto callback = [](nebula::cpp2::ErrorCode, nebula::meta::cpp2::StatsItem&) {}; @@ -420,7 +420,7 @@ TEST_F(RebuildIndexTest, RebuildEdgeIndexWithDelete) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(std::move(parts)); - parameter.set_task_specfic_paras({"103", "104"}); + parameter.set_task_specific_paras({"103", "104"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_EDGE_INDEX); @@ -482,7 +482,7 @@ TEST_F(RebuildIndexTest, RebuildEdgeIndexWithAppend) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(std::move(parts)); - parameter.set_task_specfic_paras({"103", "104"}); + parameter.set_task_specific_paras({"103", "104"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_EDGE_INDEX); @@ -526,7 +526,7 @@ TEST_F(RebuildIndexTest, RebuildEdgeIndex) { parameter.set_space_id(1); std::vector parts = {1, 2, 3, 4, 5, 6}; parameter.set_parts(std::move(parts)); - parameter.set_task_specfic_paras({"103", "104"}); + parameter.set_task_specific_paras({"103", "104"}); cpp2::AddAdminTaskRequest request; request.set_cmd(meta::cpp2::AdminCmd::REBUILD_EDGE_INDEX); diff --git a/src/storage/test/ScanEdgePropBenchmark.cpp b/src/storage/test/ScanEdgePropBenchmark.cpp index cbb26fa2106..92bb6b01cd7 100644 --- a/src/storage/test/ScanEdgePropBenchmark.cpp +++ b/src/storage/test/ScanEdgePropBenchmark.cpp @@ -195,7 +195,7 @@ TEST_P(ScanEdgePropBench, ProcessEdgeProps) { ASSERT_TRUE(code.ok()); result.mutableList().values.emplace_back(std::move(list)); } - LOG(WARNING) << "ProcessEdgeProps reader reset with vector schmeas: process " << edgeRowCount + LOG(WARNING) << "ProcessEdgeProps reader reset with vector schemas: process " << edgeRowCount << " edges takes " << watch.elapsed().count() << " us."; } { @@ -245,7 +245,7 @@ TEST_P(ScanEdgePropBench, ProcessEdgeProps) { result.mutableList().values.emplace_back(std::move(list)); } LOG(WARNING) << "ProcessEdgeProps only RowReaderV2 reset with vector " - "schmeas: process " + "schemas: process " << edgeRowCount << " edges takes " << watch.elapsed().count() << " us."; } } diff --git a/src/storage/test/StatsTaskTest.cpp b/src/storage/test/StatsTaskTest.cpp index 6ba49a74f9f..dc8746e7ee3 100644 --- a/src/storage/test/StatsTaskTest.cpp +++ b/src/storage/test/StatsTaskTest.cpp @@ -103,7 +103,7 @@ TEST_F(StatsTaskTest, StatsTagAndEdgeData) { } } - // Check statis result + // Check stats result ASSERT_EQ(nebula::meta::cpp2::JobStatus::FINISHED, statsItem.get_status()); // Three tags ASSERT_EQ(3, (*statsItem.tag_vertices_ref()).size()); @@ -168,7 +168,7 @@ TEST_F(StatsTaskTest, StatsTagAndEdgeData) { } } - // Check statis result + // Check stats result ASSERT_EQ(nebula::meta::cpp2::JobStatus::FINISHED, statsItem.get_status()); // Three tags ASSERT_EQ(3, (*statsItem.tag_vertices_ref()).size()); @@ -239,7 +239,7 @@ TEST_F(StatsTaskTest, StatsTagAndEdgeData) { } } - // Check statis result + // Check stats result ASSERT_EQ(nebula::meta::cpp2::JobStatus::FINISHED, statsItem.get_status()); // Three tags ASSERT_EQ(3, (*statsItem.tag_vertices_ref()).size()); @@ -299,7 +299,7 @@ TEST_F(StatsTaskTest, StatsTagAndEdgeData) { VertexID lastDstVertexId = ""; EdgeRanking lastRank = 0; - auto prefix = NebulaKeyUtils::vertexPrefix(part); + auto prefix = NebulaKeyUtils::tagPrefix(part); std::unique_ptr iter; auto ret = env_->kvstore_->prefix(spaceId, part, prefix, &iter); if (ret != nebula::cpp2::ErrorCode::SUCCEEDED) { diff --git a/src/storage/test/StorageHttpAdminHandlerTest.cpp b/src/storage/test/StorageHttpAdminHandlerTest.cpp index e210774925c..2a7a3e098b4 100644 --- a/src/storage/test/StorageHttpAdminHandlerTest.cpp +++ b/src/storage/test/StorageHttpAdminHandlerTest.cpp @@ -65,14 +65,14 @@ static void checkInvalidRequest(const std::string& url, const std::string& errMs ASSERT_EQ(0, request(url).find(errMsg)); } -TEST(StoragehHttpAdminHandlerTest, TestInvalidRequests) { +TEST(StorageHttpAdminHandlerTest, TestInvalidRequests) { checkInvalidRequest("/admin", "Space should not be empty"); checkInvalidRequest("/admin?space=xx", "Op should not be empty"); checkInvalidRequest("/admin?space=xx&op=yy", "Can't find space xx"); checkInvalidRequest("/admin?space=1&op=yy", "Unknown operation yy"); } -TEST(StoragehHttpAdminHandlerTest, TestSupportedOperations) { +TEST(StorageHttpAdminHandlerTest, TestSupportedOperations) { ASSERT_EQ("ok", request("/admin?space=1&op=flush")); ASSERT_EQ("ok", request("/admin?space=1&op=compact")); } diff --git a/src/storage/test/StorageHttpStatsHandlerTest.cpp b/src/storage/test/StorageHttpStatsHandlerTest.cpp index 55ad976f56c..286950ee48d 100644 --- a/src/storage/test/StorageHttpStatsHandlerTest.cpp +++ b/src/storage/test/StorageHttpStatsHandlerTest.cpp @@ -70,7 +70,7 @@ TEST(StorageHttpStatsHandlerTest, GetStatsTest) { const std::string expect = "rocksdb.bytes.read=0\n"; ASSERT_STREQ(expect.c_str(), resp.value().c_str()); } - // Get multipple stats + // Get multiple stats { auto url = "/rocksdb_stats?stats=rocksdb.bytes.read,rocksdb.block.cache.add"; auto request = diff --git a/src/storage/test/StorageIndexWriteBenchmark.cpp b/src/storage/test/StorageIndexWriteBenchmark.cpp index 0571951f32a..b76fe4edd6b 100644 --- a/src/storage/test/StorageIndexWriteBenchmark.cpp +++ b/src/storage/test/StorageIndexWriteBenchmark.cpp @@ -31,7 +31,7 @@ using NewTag = nebula::storage::cpp2::NewTag; enum class IndexENV : uint8_t { NO_INDEX = 1, ONE_INDEX = 2, - MULITPLE_INDEX = 3, + MULTIPLE_INDEX = 3, INVALID_INDEX = 4, }; @@ -97,7 +97,7 @@ std::unique_ptr memIndexMan(IndexENV type) { indexMan->addTagIndex(spaceId, -1, indexId, mockTagIndexColumns()); break; } - case IndexENV::MULITPLE_INDEX: { + case IndexENV::MULTIPLE_INDEX: { indexMan->addTagIndex(spaceId, tagId, indexId, mockTagIndexColumns()); indexMan->addTagIndex(spaceId, tagId, indexId + 1, mockTagIndexColumns()); indexMan->addTagIndex(spaceId, tagId, indexId + 2, mockTagIndexColumns()); @@ -176,7 +176,7 @@ void initEnv(IndexENV type, } void verifyDataCount(storage::StorageEnv* env, int32_t expected) { - auto prefix = NebulaKeyUtils::vertexPrefix(1); + auto prefix = NebulaKeyUtils::tagPrefix(1); std::unique_ptr iter; auto status = env->kvstore_->prefix(spaceId, 1, prefix, &iter); DCHECK(nebula::cpp2::ErrorCode::SUCCEEDED == status); @@ -315,7 +315,7 @@ void insertVerticesMultIndex() { int32_t vId = 0; BENCHMARK_SUSPEND { std::string dataPath = folly::stringPrintf("%s/%s", FLAGS_root_data_path.c_str(), "multIndex"); - initEnv(IndexENV::MULITPLE_INDEX, dataPath, env, kv, sm, im); + initEnv(IndexENV::MULTIPLE_INDEX, dataPath, env, kv, sm, im); }; while (vId < FLAGS_total_vertices_size) { @@ -361,7 +361,7 @@ int main(int argc, char** argv) { * withoutIndex: Without index, insert data only. * unmatchIndex: There are no matched indexes. * attachIndex: One index, the index contains all the columns of tag. - * duplicateVerticesIndex: One index, and insert deplicate vertices. + * duplicateVerticesIndex: One index, and insert duplicate vertices. * multipleIndex: Three indexes by one tag. * * 56 processors, Intel(R) Xeon(R) CPU E5-2697 v3 @ 2.60GHz diff --git a/src/storage/test/TestUtils.h b/src/storage/test/TestUtils.h index 49a004c8454..d82bbd8ca9f 100644 --- a/src/storage/test/TestUtils.h +++ b/src/storage/test/TestUtils.h @@ -41,7 +41,7 @@ void checkAddVerticesData(cpp2::AddVerticesRequest req, for (auto& newTag : newTagVec) { auto tagId = newTag.get_tag_id(); - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vid.getStr(), tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vid.getStr(), tagId); std::unique_ptr iter; EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, env->kvstore_->prefix(spaceId, partId, prefix, &iter)); @@ -152,7 +152,7 @@ void checkVerticesData(int32_t spaceVidLen, auto partId = part.first; auto deleteVidVec = part.second; for (auto& vid : deleteVidVec) { - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vid.getStr()); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vid.getStr()); std::unique_ptr iter; EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, env->kvstore_->prefix(spaceId, partId, prefix, &iter)); diff --git a/src/storage/test/UpdateEdgeTest.cpp b/src/storage/test/UpdateEdgeTest.cpp index 8222081eed2..86d66825c69 100644 --- a/src/storage/test/UpdateEdgeTest.cpp +++ b/src/storage/test/UpdateEdgeTest.cpp @@ -377,7 +377,7 @@ TEST(UpdateEdgeTest, Filter_Yield_Test) { auto* srcExp2 = EdgePropertyExpression::make(pool, "101", "endYear"); auto* priExp2 = ConstantExpression::make(pool, 2017L); auto* right = RelationalExpression::makeEQ(pool, srcExp2, priExp2); - // left AND right is ture + // left AND right is true auto logExp = LogicalExpression::makeAnd(pool, left, right); req.set_condition(Expression::encode(*logExp)); @@ -748,7 +748,7 @@ TEST(UpdateEdgeTest, Invalid_Filter_Test) { auto* srcExp2 = EdgePropertyExpression::make(pool, "101", "birth"); auto* priExp2 = ConstantExpression::make(pool, 1990L); auto* right = RelationalExpression::makeEQ(pool, srcExp2, priExp2); - // left AND right is ture + // left AND right is true auto logExp = LogicalExpression::makeAnd(pool, left, right); req.set_condition(Expression::encode(*logExp)); @@ -1542,7 +1542,7 @@ TEST(UpdateEdgeTest, Yield_Key_Test) { EXPECT_EQ("trade", val.getStr()); } -// Update faild, yield edge is illegal +// Update failed, yield edge is illegal TEST(UpdateEdgeTest, Yield_Illegal_Key_Test) { fs::TempDir rootPath("/tmp/UpdateEdgeTest.XXXXXX"); mock::MockCluster cluster; @@ -1649,7 +1649,7 @@ TEST(UpdateEdgeTest, Yield_Illegal_Key_Test) { EXPECT_EQ("zzzzz", val.getStr()); } -// Upsert, insert faild +// Upsert, insert failed // teamCareer filed has not default value and not nullable, not in set clause TEST(UpdateEdgeTest, Insertable_No_Default_Test) { fs::TempDir rootPath("/tmp/UpdateEdgeTest.XXXXXX"); diff --git a/src/storage/test/UpdateVertexTest.cpp b/src/storage/test/UpdateVertexTest.cpp index 32b3d1a9eb3..35dceb7d91e 100644 --- a/src/storage/test/UpdateVertexTest.cpp +++ b/src/storage/test/UpdateVertexTest.cpp @@ -58,7 +58,7 @@ static bool mockVertexData(storage::StorageEnv* env, int32_t totalParts, int32_t data.clear(); for (const auto& vertex : part.second) { TagID tagId = vertex.tId_; - auto key = NebulaKeyUtils::vertexKey(spaceVidLen, part.first, vertex.vId_, tagId); + auto key = NebulaKeyUtils::tagKey(spaceVidLen, part.first, vertex.vId_, tagId); auto schema = env->schemaMan_->getTagSchema(spaceId, tagId); if (!schema) { LOG(ERROR) << "Invalid tagId " << tagId; @@ -184,7 +184,7 @@ TEST(UpdateVertexTest, No_Filter_Test) { EXPECT_EQ(1, (*resp.props_ref()).rows[0].values[5].getInt()); // get player from kvstore directly - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -234,7 +234,7 @@ TEST(UpdateVertexTest, Filter_Yield_Test2) { auto* srcExp2 = SourcePropertyExpression::make(pool, "1", "endYear"); auto* priExp2 = ConstantExpression::make(pool, 2017L); auto* right = RelationalExpression::makeEQ(pool, srcExp2, priExp2); - // left AND right is ture + // left AND right is true auto logExp = LogicalExpression::makeAnd(pool, left, right); req.set_condition(Expression::encode(*logExp)); @@ -303,7 +303,7 @@ TEST(UpdateVertexTest, Filter_Yield_Test2) { // get player from kvstore directly // Because no update, the value is old - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -406,7 +406,7 @@ TEST(UpdateVertexTest, Insertable_Test) { EXPECT_EQ(1, (*resp.props_ref()).rows[0].values[5].getInt()); // get player from kvstore directly - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -487,7 +487,7 @@ TEST(UpdateVertexTest, Invalid_Update_Prop_Test) { // get player from kvstore directly // Because no update, the value is old - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -537,7 +537,7 @@ TEST(UpdateVertexTest, Invalid_Filter_Test) { auto* srcExp2 = SourcePropertyExpression::make(pool, "1", "birth"); auto* priExp2 = ConstantExpression::make(pool, 1990L); auto* right = RelationalExpression::makeEQ(pool, srcExp2, priExp2); - // left AND right is ture + // left AND right is true auto logExp = LogicalExpression::makeAnd(pool, left, right); req.set_condition(Expression::encode(*logExp)); @@ -587,7 +587,7 @@ TEST(UpdateVertexTest, Invalid_Filter_Test) { // get player from kvstore directly // Because no update, the value is old - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -704,7 +704,7 @@ TEST(UpdateVertexTest, Insertable_Filter_Value_Test) { EXPECT_EQ(1, (*resp.props_ref()).rows[0].values[5].getInt()); // get player from kvstore directly - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -737,7 +737,7 @@ TEST(UpdateVertexTest, CorruptDataTest) { auto partId = std::hash()("Lonzo Ball") % parts + 1; VertexID vertexId("Lonzo Ball"); - auto key = NebulaKeyUtils::vertexKey(spaceVidLen, partId, vertexId, 1); + auto key = NebulaKeyUtils::tagKey(spaceVidLen, partId, vertexId, 1); std::vector data; data.emplace_back(std::make_pair(key, "")); folly::Baton<> baton; @@ -954,7 +954,7 @@ TEST(UpdateVertexTest, TTL_Insert_No_Exist_Test) { EXPECT_EQ(1, (*resp.props_ref()).rows[0].values[5].getInt()); // get player from kvstore directly - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -1072,10 +1072,10 @@ TEST(UpdateVertexTest, TTL_Insert_Test) { EXPECT_EQ("Tim Duncan", (*resp.props_ref()).rows[0].values[4].getStr()); EXPECT_EQ(1, (*resp.props_ref()).rows[0].values[5].getInt()); - // Get player from kvstore directly, ttl expired data can be readed + // Get player from kvstore directly, ttl expired data can be readded // First record is inserted record data // Second record is expired ttl data - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -1112,9 +1112,9 @@ TEST(UpdateVertexTest, TTL_Insert_Test) { EXPECT_EQ(1, count); } -// upsert, insert faild +// upsert, insert failed // age filed has not default value and not nullable, not in set clause -TEST(UpdateVertexTest, Insertable_No_Defalut_Test) { +TEST(UpdateVertexTest, Insertable_No_Default_Test) { fs::TempDir rootPath("/tmp/UpdateVertexTest.XXXXXX"); mock::MockCluster cluster; cluster.initStorageKV(rootPath.path()); @@ -1256,7 +1256,7 @@ TEST(UpdateVertexTest, Insertable_In_Set_Test) { EXPECT_EQ(1, (*resp.props_ref()).rows[0].values[4].getInt()); // get player from kvstore directly - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -1328,7 +1328,7 @@ TEST(UpdateVertexTest, Update_Multi_tag_Test) { EXPECT_EQ(1, (*resp.result_ref()).failed_parts.size()); // get player from kvstore directly - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -1398,7 +1398,7 @@ TEST(UpdateVertexTest, Upsert_Multi_tag_Test) { EXPECT_EQ(1, (*resp.result_ref()).failed_parts.size()); // get player from kvstore directly - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); @@ -1467,7 +1467,7 @@ TEST(UpdateVertexTest, Upsert_Field_Type_And_Value_Match_Test) { EXPECT_EQ(1, (*resp.result_ref()).failed_parts.size()); // get player from kvstore directly - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen, partId, vertexId, tagId); std::unique_ptr iter; auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret); diff --git a/src/storage/transaction/ChainAddEdgesProcessorLocal.cpp b/src/storage/transaction/ChainAddEdgesProcessorLocal.cpp index 8587d5021b8..182484a4de0 100644 --- a/src/storage/transaction/ChainAddEdgesProcessorLocal.cpp +++ b/src/storage/transaction/ChainAddEdgesProcessorLocal.cpp @@ -468,10 +468,10 @@ std::string ChainAddEdgesProcessorLocal::makeReadableEdge(const cpp2::AddEdgesRe * * storage will insert datetime() as default value on both * in/out edge, but they will calculate independent - * which lead to inconsistance + * which lead to inconsistency * - * that's why we need to replace the inconsistance prone value - * at the monment the request comes + * that's why we need to replace the inconsistency prone value + * at the moment the request comes * */ void ChainAddEdgesProcessorLocal::replaceNullWithDefaultValue(cpp2::AddEdgesRequest& req) { auto& edgesOfPart = *req.parts_ref(); diff --git a/src/storage/transaction/ChainAddEdgesProcessorLocal.h b/src/storage/transaction/ChainAddEdgesProcessorLocal.h index 9f4962ba048..8e2329158a2 100644 --- a/src/storage/transaction/ChainAddEdgesProcessorLocal.h +++ b/src/storage/transaction/ChainAddEdgesProcessorLocal.h @@ -86,7 +86,7 @@ class ChainAddEdgesProcessorLocal : public BaseProcessor, /** * @brief a normal AddEdgeRequest may contain multi edges * even though they will fail or succeed as a batch in this time - * some of them may by overwrite by othere request + * some of them may by overwrite by other request * so when resume each edge */ cpp2::AddEdgesRequest makeSingleEdgeRequest(PartitionID partId, const cpp2::NewEdge& edge); @@ -114,10 +114,10 @@ class ChainAddEdgesProcessorLocal : public BaseProcessor, * * storage will insert datetime() as default value on both * in/out edge, but they will calculate independent - * which lead to inconsistance + * which lead to inconsistency * - * that why we need to replace the inconsistance prone value - * at the monment the request comes + * that why we need to replace the inconsistency prone value + * at the moment the request comes * */ void replaceNullWithDefaultValue(cpp2::AddEdgesRequest& req); diff --git a/src/storage/transaction/ConsistUtil.cpp b/src/storage/transaction/ConsistUtil.cpp index 05854f8a949..4edea1dfe0e 100644 --- a/src/storage/transaction/ConsistUtil.cpp +++ b/src/storage/transaction/ConsistUtil.cpp @@ -62,7 +62,7 @@ RequestType ConsistUtil::parseType(folly::StringPiece val) { case 'a': return RequestType::INSERT; default: - LOG(FATAL) << "shoule not happend, identifier is " << identifier; + LOG(FATAL) << "should not happen, identifier is " << identifier; } } diff --git a/src/storage/transaction/ResumeUpdateProcessor.h b/src/storage/transaction/ResumeUpdateProcessor.h index d0ff1d7766b..ea6272e43ef 100644 --- a/src/storage/transaction/ResumeUpdateProcessor.h +++ b/src/storage/transaction/ResumeUpdateProcessor.h @@ -12,7 +12,7 @@ namespace storage { /** * @brief - * if the TxnManager backgroud resume thread found a prime key + * if the TxnManager background resume thread found a prime key * it will create this processor to resume the complete update process */ class ResumeUpdateProcessor : public ChainUpdateEdgeProcessorLocal { diff --git a/src/storage/transaction/ResumeUpdateRemoteProcessor.cpp b/src/storage/transaction/ResumeUpdateRemoteProcessor.cpp index b2501cc920f..aca10ccad0c 100644 --- a/src/storage/transaction/ResumeUpdateRemoteProcessor.cpp +++ b/src/storage/transaction/ResumeUpdateRemoteProcessor.cpp @@ -45,7 +45,7 @@ folly::SemiFuture ResumeUpdateRemoteProcessor::processLocal(Code code) { forwardToDelegateProcessor(); return code; } else { - // we can't decide if the double prime shoule be deleted. + // we can't decide if the double prime should be deleted. // so do nothing } diff --git a/src/storage/transaction/ResumeUpdateRemoteProcessor.h b/src/storage/transaction/ResumeUpdateRemoteProcessor.h index dbd9b780796..d1ce5d93438 100644 --- a/src/storage/transaction/ResumeUpdateRemoteProcessor.h +++ b/src/storage/transaction/ResumeUpdateRemoteProcessor.h @@ -12,7 +12,7 @@ namespace storage { /** * @brief - * if the TxnManager backgroud resume thread found a prime key + * if the TxnManager background resume thread found a prime key * it will create this processor to resume the complete update process */ class ResumeUpdateRemoteProcessor : public ChainUpdateEdgeProcessorLocal { diff --git a/src/tools/db-dump/CMakeLists.txt b/src/tools/db-dump/CMakeLists.txt index 62f272621a0..8618259bf4b 100644 --- a/src/tools/db-dump/CMakeLists.txt +++ b/src/tools/db-dump/CMakeLists.txt @@ -16,6 +16,7 @@ set(tools_test_deps $ $ $ + $ $ $ $ diff --git a/src/tools/db-dump/DbDumpTool.cpp b/src/tools/db-dump/DbDumpTool.cpp index f412b758299..20bf447bd61 100644 --- a/src/tools/db-dump/DbDumpTool.cpp +++ b/src/tools/db-dump/DbDumpTool.cpp @@ -21,28 +21,28 @@ void printHelp() { Default: ./ --meta_server= - A list of meta severs' ip:port seperated by comma. + A list of meta severs' ip:port separated by comma. Default: 127.0.0.1:45500 --mode= scan | stat scan: print to screen when records meet the condition, and also print statistics to screen in final. stat: print statistics to screen. - Defualt: scan + Default: scan --vids= - A list of vid seperated by comma. This parameter means vertex_id/edge_src_id + A list of vid separated by comma. This parameter means vertex_id/edge_src_id Would scan the whole space's records if it is not given. --parts= - A list of partition id seperated by comma. - Would output all patitions if it is not given. + A list of partition id separated by comma. + Would output all partitions if it is not given. --tags= - A list of tag name seperated by comma. + A list of tag name separated by comma. --edges= - A list of edge name seperated by comma. + A list of edge name separated by comma. --limit= A positive number that limits the output. diff --git a/src/tools/db-dump/DbDumper.cpp b/src/tools/db-dump/DbDumper.cpp index 3ae9d40fd0d..2f0fd52b15a 100644 --- a/src/tools/db-dump/DbDumper.cpp +++ b/src/tools/db-dump/DbDumper.cpp @@ -13,10 +13,10 @@ DEFINE_string(space_name, "", "The space name."); DEFINE_string(db_path, "./", "Path to rocksdb."); DEFINE_string(meta_server, "127.0.0.1:45500", "Meta servers' address."); DEFINE_string(mode, "scan", "Dump mode, scan | stat"); -DEFINE_string(parts, "", "A list of partition id seperated by comma."); -DEFINE_string(vids, "", "A list of vertex ids seperated by comma."); -DEFINE_string(tags, "", "A list of tag name seperated by comma."); -DEFINE_string(edges, "", "A list of edge name seperated by comma."); +DEFINE_string(parts, "", "A list of partition id separated by comma."); +DEFINE_string(vids, "", "A list of vertex ids separated by comma."); +DEFINE_string(tags, "", "A list of tag name separated by comma."); +DEFINE_string(edges, "", "A list of edge name separated by comma."); DEFINE_int64(limit, 1000, "Limit to output."); namespace nebula { @@ -110,7 +110,7 @@ Status DbDumper::initParams() { folly::splitTo(',', FLAGS_tags, std::inserter(tags, tags.begin()), true); folly::splitTo(',', FLAGS_edges, std::inserter(edges, edges.begin()), true); } catch (const std::exception& e) { - return Status::Error("Parse parts/vetexIds/tags/edges error: %s", e.what()); + return Status::Error("Parse parts/vertexIds/tags/edges error: %s", e.what()); } for (auto& tagName : tags) { @@ -129,7 +129,7 @@ Status DbDumper::initParams() { } if (FLAGS_mode.compare("scan") != 0 && FLAGS_mode.compare("stat") != 0) { - return Status::Error("Unkown mode '%s'.", FLAGS_mode.c_str()); + return Status::Error("Unknown mode '%s'.", FLAGS_mode.c_str()); } return Status::OK(); } @@ -219,7 +219,7 @@ void DbDumper::run() { continue; } auto partId = metaClient_->partId(partNum_, vid); - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen_, partId, vid); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vid); seek(prefix); } break; @@ -246,7 +246,7 @@ void DbDumper::run() { } auto partId = metaClient_->partId(partNum_, vid); for (auto tagId : tagIds_) { - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen_, partId, vid, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vid, tagId); seek(prefix); } } @@ -271,7 +271,7 @@ void DbDumper::run() { } auto partId = metaClient_->partId(partNum_, vid); for (auto tagId : tagIds_) { - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen_, partId, vid, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vid, tagId); seek(prefix); } } @@ -280,7 +280,7 @@ void DbDumper::run() { case 0b1000: { // specified part, seek with prefix and print them all for (auto partId : parts_) { - auto vertexPrefix = NebulaKeyUtils::vertexPrefix(partId); + auto vertexPrefix = NebulaKeyUtils::tagPrefix(partId); seek(vertexPrefix); auto edgePrefix = NebulaKeyUtils::edgePrefix(partId); seek(edgePrefix); @@ -302,7 +302,7 @@ void DbDumper::run() { beforePrintVertex_.emplace_back(printIfTagFound); beforePrintEdge_.emplace_back(noPrint); for (auto partId : parts_) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); seek(prefix); } break; @@ -321,7 +321,7 @@ void DbDumper::run() { beforePrintVertex_.emplace_back(printIfTagFound); beforePrintEdge_.emplace_back(noPrint); for (auto partId : parts_) { - auto prefix = NebulaKeyUtils::vertexPrefix(partId); + auto prefix = NebulaKeyUtils::tagPrefix(partId); seek(prefix); } break; @@ -333,7 +333,7 @@ void DbDumper::run() { if (!isValidVidLen(vid)) { continue; } - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen_, partId, vid); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vid); seek(prefix); } } @@ -362,7 +362,7 @@ void DbDumper::run() { continue; } for (auto tagId : tagIds_) { - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen_, partId, vid, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vid, tagId); seek(prefix); } } @@ -389,7 +389,7 @@ void DbDumper::run() { continue; } for (auto tagId : tagIds_) { - auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen_, partId, vid, tagId); + auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vid, tagId); seek(prefix); } } @@ -440,7 +440,7 @@ void DbDumper::iterates(kvstore::RocksPrefixIter* it) { auto key = it->key(); auto value = it->val(); - if (NebulaKeyUtils::isVertex(spaceVidLen_, key)) { + if (NebulaKeyUtils::isTag(spaceVidLen_, key)) { // filter the data bool isFiltered = false; for (auto& cb : beforePrintVertex_) { diff --git a/src/tools/db-upgrade/CMakeLists.txt b/src/tools/db-upgrade/CMakeLists.txt index 584d03acf2d..d43c203ab71 100644 --- a/src/tools/db-upgrade/CMakeLists.txt +++ b/src/tools/db-upgrade/CMakeLists.txt @@ -24,6 +24,7 @@ nebula_add_executable( $ $ $ + $ $ $ $ diff --git a/src/tools/db-upgrade/DbUpgrader.cpp b/src/tools/db-upgrade/DbUpgrader.cpp index 3628cb7474f..40c638a6354 100644 --- a/src/tools/db-upgrade/DbUpgrader.cpp +++ b/src/tools/db-upgrade/DbUpgrader.cpp @@ -269,7 +269,7 @@ void UpgraderSpace::runPartV1() { auto strVid = std::string(reinterpret_cast(&vId), sizeof(vId)); auto newTagSchema = it->second.back().get(); // Generate 2.0 key - auto newKey = NebulaKeyUtils::vertexKey(spaceVidLen_, partId, strVid, tagId); + auto newKey = NebulaKeyUtils::tagKey(spaceVidLen_, partId, strVid, tagId); auto val = iter->val(); auto reader = RowReaderWrapper::getTagPropReader(schemaMan_, spaceId_, tagId, val); if (!reader) { @@ -372,7 +372,7 @@ void UpgraderSpace::doProcessV1() { // Parallel process part auto partConcurrency = std::min(static_cast(FLAGS_max_concurrent_parts), parts_.size()); - LOG(INFO) << "Max concurrenct parts: " << partConcurrency; + LOG(INFO) << "Max concurrent parts: " << partConcurrency; unFinishedPart_ = parts_.size(); @@ -482,7 +482,7 @@ void UpgraderSpace::runPartV2() { auto newTagSchema = it->second.back().get(); // Generate 2.0 key - auto newKey = NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vId, tagId); + auto newKey = NebulaKeyUtils::tagKey(spaceVidLen_, partId, vId, tagId); auto val = iter->val(); auto reader = RowReaderWrapper::getTagPropReader(schemaMan_, spaceId_, tagId, val); if (!reader) { @@ -581,7 +581,7 @@ void UpgraderSpace::doProcessV2() { // Parallel process part auto partConcurrency = std::min(static_cast(FLAGS_max_concurrent_parts), parts_.size()); - LOG(INFO) << "Max concurrenct parts: " << partConcurrency; + LOG(INFO) << "Max concurrent parts: " << partConcurrency; unFinishedPart_ = parts_.size(); LOG(INFO) << "Start to handle vertex/edge/index of parts data in space id " << spaceId_; @@ -1073,7 +1073,7 @@ void DbUpgrader::run() { // Parallel process space auto spaceConcurrency = std::min(static_cast(FLAGS_max_concurrent_spaces), upgraderSpaces.size()); - LOG(INFO) << "Max concurrenct spaces: " << spaceConcurrency; + LOG(INFO) << "Max concurrent spaces: " << spaceConcurrency; for (size_t i = 0; i < spaceConcurrency; ++i) { pool_->add(std::bind(&DbUpgrader::doSpace, this)); diff --git a/src/tools/db-upgrade/DbUpgrader.h b/src/tools/db-upgrade/DbUpgrader.h index a90f181b875..6851893f739 100644 --- a/src/tools/db-upgrade/DbUpgrader.h +++ b/src/tools/db-upgrade/DbUpgrader.h @@ -112,7 +112,7 @@ class UpgraderSpace { void runPartV2(); public: - // Souce data path + // Source data path std::string srcPath_; // Destination data path std::string dstPath_; @@ -192,7 +192,7 @@ class DbUpgrader { meta::MetaClient* metaClient_; meta::ServerBasedSchemaManager* schemaMan_; meta::IndexManager* indexMan_; - // Souce data path + // Source data path std::string srcPath_; // Destination data path diff --git a/src/tools/db-upgrade/DbUpgraderTool.cpp b/src/tools/db-upgrade/DbUpgraderTool.cpp index f7702a9cd5b..94b35c51d22 100644 --- a/src/tools/db-upgrade/DbUpgraderTool.cpp +++ b/src/tools/db-upgrade/DbUpgraderTool.cpp @@ -36,7 +36,7 @@ void printHelp() { src_db_path and dst_db_path must be different. --upgrade_meta_server= - A list of meta severs' ip:port seperated by comma. + A list of meta severs' ip:port separated by comma. Default: 127.0.0.1:45500 --upgrade_version=<1|2> @@ -172,7 +172,7 @@ int main(int argc, char* argv[]) { LOG(INFO) << "Prepare phase end"; // Upgrade data - LOG(INFO) << "Upgrade phase bengin"; + LOG(INFO) << "Upgrade phase begin"; // The data path in storage conf is generally one, not too many. // So there is no need to control the number of threads here. diff --git a/src/tools/db-upgrade/NebulaKeyUtilsV1.h b/src/tools/db-upgrade/NebulaKeyUtilsV1.h index 9f14073d2ba..3226f34b626 100644 --- a/src/tools/db-upgrade/NebulaKeyUtilsV1.h +++ b/src/tools/db-upgrade/NebulaKeyUtilsV1.h @@ -181,7 +181,7 @@ class NebulaKeyUtilsV1 final { } static folly::StringPiece keyWithNoVersion(const folly::StringPiece& rawKey) { - // TODO(heng) We should change the method if varint data version supportted. + // TODO(heng) We should change the method if varint data version supported. return rawKey.subpiece(0, rawKey.size() - sizeof(int64_t)); } diff --git a/src/tools/db-upgrade/NebulaKeyUtilsV2.cpp b/src/tools/db-upgrade/NebulaKeyUtilsV2.cpp index 4891adb3f98..8a1a0f429c6 100644 --- a/src/tools/db-upgrade/NebulaKeyUtilsV2.cpp +++ b/src/tools/db-upgrade/NebulaKeyUtilsV2.cpp @@ -16,7 +16,7 @@ bool NebulaKeyUtilsV2::isValidVidLen(size_t vIdLen, VertexID srcVId, VertexID ds } // static -std::string NebulaKeyUtilsV2::vertexKey( +std::string NebulaKeyUtilsV2::tagKey( size_t vIdLen, PartitionID partId, VertexID vId, TagID tagId, TagVersion tv) { CHECK_GE(vIdLen, vId.size()); tagId &= kTagMaskSet; diff --git a/src/tools/db-upgrade/NebulaKeyUtilsV2.h b/src/tools/db-upgrade/NebulaKeyUtilsV2.h index 1f7a79b6556..ad35cb5ae26 100644 --- a/src/tools/db-upgrade/NebulaKeyUtilsV2.h +++ b/src/tools/db-upgrade/NebulaKeyUtilsV2.h @@ -31,7 +31,7 @@ enum class NebulaKeyTypeV2 : uint32_t { * space property. * * LockKeyUtils: - * EdgeKeyWithNoVersion + placeHolder(8) + version(8) + surfix(2) + * EdgeKeyWithNoVersion + placeHolder(8) + version(8) + suffix(2) * */ const std::string kLockSuffix = "lk"; // NOLINT @@ -50,9 +50,9 @@ class NebulaKeyUtilsV2 final { static bool isValidVidLen(size_t vIdLen, VertexID srcvId, VertexID dstvId = ""); /** - * Generate vertex key for kv store + * Generate tag key for kv store * */ - static std::string vertexKey( + static std::string tagKey( size_t vIdLen, PartitionID partId, VertexID vId, TagID tagId, TagVersion tv); /** @@ -224,7 +224,7 @@ class NebulaKeyUtilsV2 final { } static folly::StringPiece keyWithNoVersion(const folly::StringPiece& rawKey) { - // TODO(heng) We should change the method if varint data version supportted. + // TODO(heng) We should change the method if varint data version supported. return rawKey.subpiece(0, rawKey.size() - sizeof(int64_t)); } @@ -244,14 +244,14 @@ class NebulaKeyUtilsV2 final { static EdgeVersion getLockVersion(const folly::StringPiece& rawKey) { // TODO(liuyu) We should change the method if varint data version - // supportted. + // supported. auto offset = rawKey.size() - sizeof(int64_t) * 2 - kLockSuffix.size(); return readInt(rawKey.data() + offset, sizeof(int64_t)); } static folly::StringPiece lockWithNoVersion(const folly::StringPiece& rawKey) { // TODO(liuyu) We should change the method if varint data version - // supportted. + // supported. return rawKey.subpiece(0, rawKey.size() - sizeof(int64_t) * 2 - kLockSuffix.size()); } diff --git a/src/tools/meta-dump/CMakeLists.txt b/src/tools/meta-dump/CMakeLists.txt index c5fa9d565d8..9fe5765a612 100644 --- a/src/tools/meta-dump/CMakeLists.txt +++ b/src/tools/meta-dump/CMakeLists.txt @@ -21,6 +21,7 @@ nebula_add_executable( $ $ $ + $ $ $ $ diff --git a/src/tools/simple-kv-verify/CMakeLists.txt b/src/tools/simple-kv-verify/CMakeLists.txt index 32e8eafa5ee..cf65e874429 100644 --- a/src/tools/simple-kv-verify/CMakeLists.txt +++ b/src/tools/simple-kv-verify/CMakeLists.txt @@ -18,6 +18,7 @@ nebula_add_executable( $ $ $ + $ $ $ $ diff --git a/src/tools/storage-perf/CMakeLists.txt b/src/tools/storage-perf/CMakeLists.txt index ea4d1dfab25..deb1bd67277 100644 --- a/src/tools/storage-perf/CMakeLists.txt +++ b/src/tools/storage-perf/CMakeLists.txt @@ -14,6 +14,7 @@ set(perf_test_deps $ $ $ + $ $ $ $ diff --git a/src/tools/storage-perf/StorageIntegrityTool.cpp b/src/tools/storage-perf/StorageIntegrityTool.cpp index 287136ee31b..e67c96579cc 100644 --- a/src/tools/storage-perf/StorageIntegrityTool.cpp +++ b/src/tools/storage-perf/StorageIntegrityTool.cpp @@ -13,7 +13,7 @@ DEFINE_string(meta_server_addrs, "", "meta server address"); DEFINE_int32(io_threads, 10, "client io threads"); -DEFINE_int32(partition_num, 1024, "partititon for space"); +DEFINE_int32(partition_num, 1024, "partition for space"); DEFINE_string(space_name, "test_space", "the space name"); DEFINE_string(tag_name, "test_tag", "the tag name"); DEFINE_string(prop_name, "test_prop", "the property name"); @@ -33,7 +33,7 @@ namespace storage { * * There are some gflags we need to pay attention: * 1. The space's replica must be 1, because we don't have retry in - * StorageClient, we will update it after we suppport preheat. The tag must have + * StorageClient, we will update it after we support preheat. The tag must have * only one int property, which is prop_name. * 2. If the space and tag doesn't exists, it will try to create one, maybe you * need to set heartbeat_interval_secs to make sure the storage service has load diff --git a/src/tools/storage-perf/StoragePerfTool.cpp b/src/tools/storage-perf/StoragePerfTool.cpp index df8e3a59662..b7336097245 100644 --- a/src/tools/storage-perf/StoragePerfTool.cpp +++ b/src/tools/storage-perf/StoragePerfTool.cpp @@ -313,7 +313,7 @@ class Perf { if (!resps.succeeded()) { LOG(ERROR) << "Request failed!"; } else { - VLOG(3) << "request successed!"; + VLOG(3) << "request succeeded!"; } this->finishedRequests_++; auto now = time::WallClock::fastNowInMicroSec(); @@ -342,7 +342,7 @@ class Perf { << apache::thrift::util::enumNameSafe(entry.second); } } else { - VLOG(1) << "request successed!"; + VLOG(1) << "request succeeded!"; } this->finishedRequests_++; auto now = time::WallClock::fastNowInMicroSec(); @@ -368,7 +368,7 @@ class Perf { if (!resps.succeeded()) { LOG(ERROR) << "Request failed!"; } else { - VLOG(3) << "request successed!"; + VLOG(3) << "request succeeded!"; } this->finishedRequests_++; auto now = time::WallClock::fastNowInMicroSec(); @@ -401,7 +401,7 @@ class Perf { if (!resps.succeeded()) { LOG(ERROR) << "Request failed!"; } else { - VLOG(3) << "request successed!"; + VLOG(3) << "request succeeded!"; } this->finishedRequests_++; auto now = time::WallClock::fastNowInMicroSec(); @@ -426,7 +426,7 @@ class Perf { if (!resps.succeeded()) { LOG(ERROR) << "Request failed!"; } else { - VLOG(3) << "request successed!"; + VLOG(3) << "request succeeded!"; } this->finishedRequests_++; auto now = time::WallClock::fastNowInMicroSec(); diff --git a/tests/admin/test_configs.py b/tests/admin/test_configs.py index 9c87734c9f6..2a8fe58736f 100644 --- a/tests/admin/test_configs.py +++ b/tests/admin/test_configs.py @@ -60,7 +60,7 @@ def test_configs(self): expected_result = [ ['GRAPH', 'v', 'int', 'MUTABLE', v], ['GRAPH', 'minloglevel', 'int', 'MUTABLE', 0], - ['GRAPH', 'slow_op_threshhold_ms', 'int', 'MUTABLE', 50], + ['GRAPH', 'slow_op_threshold_ms', 'int', 'MUTABLE', 100], ['GRAPH', 'heartbeat_interval_secs', 'int', 'MUTABLE', 1], ['GRAPH', 'meta_client_retry_times', 'int', 'MUTABLE', 3], ['GRAPH', 'accept_partial_success', 'bool', 'MUTABLE', False], @@ -80,7 +80,7 @@ def test_configs(self): ['STORAGE', 'wal_ttl', 'int', 'MUTABLE', 14400], ['STORAGE', 'minloglevel', 'int', 'MUTABLE', 0], ['STORAGE', 'custom_filter_interval_secs', 'int', 'MUTABLE', 86400], - ['STORAGE', 'slow_op_threshhold_ms', 'int', 'MUTABLE', 50], + ['STORAGE', 'slow_op_threshold_ms', 'int', 'MUTABLE', 100], ['STORAGE', 'heartbeat_interval_secs', 'int', 'MUTABLE', 1], ['STORAGE', 'meta_client_retry_times', 'int', 'MUTABLE', 3], ['STORAGE', 'rocksdb_db_options', 'map', 'MUTABLE', {}], @@ -118,7 +118,7 @@ def test_configs(self): ''') self.check_resp_succeeded(resp) - @pytest.mark.skip("The change of minloglevel will infulence the whole test.") + @pytest.mark.skip("The change of minloglevel will influence the whole test.") def test_update_configs(self): # set and get a config of all module resp = self.client.execute('UPDATE CONFIGS minloglevel={}'.format(2)) diff --git a/tests/admin/test_listener.py b/tests/admin/test_listener.py index 3fe4f95ade8..f59e0f8879b 100644 --- a/tests/admin/test_listener.py +++ b/tests/admin/test_listener.py @@ -22,7 +22,7 @@ def test_listener(self): resp = self.client.execute('ADD LISTENER ELASTICSEARCH {}:{}'.format(storage_ip, storage_port)) self.check_resp_failed(resp) - # Add non-existen host + # Add nonexistent host resp = self.client.execute('ADD LISTENER ELASTICSEARCH 127.0.0.1:8899') self.check_resp_succeeded(resp) diff --git a/tests/bench/data_generate.py b/tests/bench/data_generate.py index 55ca5577c7c..55ac70e9ee6 100644 --- a/tests/bench/data_generate.py +++ b/tests/bench/data_generate.py @@ -7,7 +7,7 @@ import string -def insert_vertexs(client, ns, batchCount, batchSize): +def insert_vertices(client, ns, batchCount, batchSize): resp = client.execute('USE ' + ns) client.check_resp_succeeded(resp) for i in range(batchCount): diff --git a/tests/bench/delete.py b/tests/bench/delete.py index 8a93efe6af7..42e129e6dcc 100644 --- a/tests/bench/delete.py +++ b/tests/bench/delete.py @@ -2,7 +2,7 @@ import pytest from graph import ttypes from tests.common.nebula_test_suite import NebulaTestSuite -from tests.bench.data_generate import insert_vertexs, insert_edges +from tests.bench.data_generate import insert_vertices, insert_edges class TestDeleteBench(NebulaTestSuite): @@ -29,7 +29,7 @@ def prepare(self): self.execute('CREATE EDGE IF NOT EXISTS like(likeness int)') self.check_resp_succeeded(resp) time.sleep(4) - insert_vertexs(self, "benchdeletespace", 50, 20000) + insert_vertices(self, "benchdeletespace", 50, 20000) insert_edges(self, "benchdeletespace", 50, 20000) @classmethod diff --git a/tests/bench/lookup.py b/tests/bench/lookup.py index fc6f766641e..81eeaa5c011 100644 --- a/tests/bench/lookup.py +++ b/tests/bench/lookup.py @@ -2,7 +2,7 @@ import pytest from graph import ttypes from tests.common.nebula_test_suite import NebulaTestSuite -from tests.bench.data_generate import insert_vertexs, insert_edges +from tests.bench.data_generate import insert_vertices, insert_edges class TestLookupBench(NebulaTestSuite): @@ -26,7 +26,7 @@ def prepare(self): 'CREATE TAG index IF NOT EXISTS personAge on person(age)') self.check_resp_succeeded(resp) time.sleep(4) - insert_vertexs(self, "benchlookupspace", 50, 20000) + insert_vertices(self, "benchlookupspace", 50, 20000) self.execute('CREATE EDGE IF NOT EXISTS like(likeness int)') self.check_resp_succeeded(resp) time.sleep(4) diff --git a/tests/common/plan_differ.py b/tests/common/plan_differ.py index f9d8800cc3d..132cbb6a809 100644 --- a/tests/common/plan_differ.py +++ b/tests/common/plan_differ.py @@ -182,16 +182,16 @@ def _extract_dict_from_obj(self, obj) -> dict: def _validate_expect(self, rows, column_names): # Check expected plan column if self.ID not in column_names: - self._err_msg = "Plan node id column is missing in expectde plan" + self._err_msg = "Plan node id column is missing in expected plan" return False if self.NAME not in column_names: - self._err_msg = "Plan node name column is missing in expectde plan" + self._err_msg = "Plan node name column is missing in expected plan" return False if self.DEPENDS not in column_names: - self._err_msg = "Plan node dependencies column is missing in expectde plan" + self._err_msg = "Plan node dependencies column is missing in expected plan" return False if self.OP_INFO not in column_names: - self._err_msg = "Plan node operator info column is missing in expectde plan" + self._err_msg = "Plan node operator info column is missing in expected plan" return False id_idx_dict = {} @@ -199,7 +199,7 @@ def _validate_expect(self, rows, column_names): for i in range(len(rows)): node_id = rows[i][0] if not node_id: - self._err_msg = "Plan node id is missing in expectde plan" + self._err_msg = "Plan node id is missing in expected plan" return False id_idx_dict[int(node_id)] = i diff --git a/tests/common/utils.py b/tests/common/utils.py index 8bff391612c..6867835015f 100644 --- a/tests/common/utils.py +++ b/tests/common/utils.py @@ -109,7 +109,7 @@ def compare_value(real, expect): esrc, edst = eedge.src, eedge.dst if eedge.type < 0: esrc, edst = edst, esrc - # ignore props comparation + # ignore props comparison return rsrc == esrc and rdst == edst \ and redge.ranking == eedge.ranking \ and redge.name == eedge.name diff --git a/tests/data/nba.ngql b/tests/data/nba.ngql index a1e4402fcab..4b84145723e 100644 --- a/tests/data/nba.ngql +++ b/tests/data/nba.ngql @@ -75,7 +75,7 @@ VALUES "Dirk Nowitzki": ("Dirk Nowitzki", 40), "Paul George": ("Paul George", 28), "Grant Hill": ("Grant Hill", 46), - "Shaquile O'Neal": ("Shaquile O'Neal", 47), + "Shaquille O'Neal": ("Shaquille O'Neal", 47), "JaVale McGee": ("JaVale McGee", 31), "Dwight Howard": ("Dwight Howard", 33); @@ -256,12 +256,12 @@ VALUES "Grant Hill" -> "Magic": (2000, 2007), "Grant Hill" -> "Suns": (2007, 2012), "Grant Hill" -> "Clippers": (2012, 2013), - "Shaquile O'Neal" -> "Magic": (1992, 1996), - "Shaquile O'Neal" -> "Lakers": (1996, 2004), - "Shaquile O'Neal" -> "Heat": (2004, 2008), - "Shaquile O'Neal" -> "Suns": (2008, 2009), - "Shaquile O'Neal" -> "Cavaliers": (2009, 2010), - "Shaquile O'Neal" -> "Celtics": (2010, 2011), + "Shaquille O'Neal" -> "Magic": (1992, 1996), + "Shaquille O'Neal" -> "Lakers": (1996, 2004), + "Shaquille O'Neal" -> "Heat": (2004, 2008), + "Shaquille O'Neal" -> "Suns": (2008, 2009), + "Shaquille O'Neal" -> "Cavaliers": (2009, 2010), + "Shaquille O'Neal" -> "Celtics": (2010, 2011), "JaVale McGee" -> "Wizards": (2008, 2012), "JaVale McGee" -> "Nuggets": (2012, 2015), "JaVale McGee" -> "Mavericks": (2015, 2016), @@ -331,7 +331,7 @@ VALUES "Joel Embiid" -> "Ben Simmons": (80), "Damian Lillard" -> "LaMarcus Aldridge": (80), "Yao Ming" -> "Tracy McGrady": (90), - "Yao Ming" -> "Shaquile O'Neal": (90), + "Yao Ming" -> "Shaquille O'Neal": (90), "Dejounte Murray" -> "Tim Duncan": (99), "Dejounte Murray" -> "Tony Parker": (99), "Dejounte Murray" -> "Manu Ginobili": (99), @@ -357,8 +357,8 @@ VALUES "Dirk Nowitzki" -> "Dwyane Wade": (10), "Paul George" -> "Russell Westbrook": (95), "Grant Hill" -> "Tracy McGrady": (90), - "Shaquile O'Neal" -> "JaVale McGee": (100), - "Shaquile O'Neal" -> "Tim Duncan": (80); + "Shaquille O'Neal" -> "JaVale McGee": (100), + "Shaquille O'Neal" -> "Tim Duncan": (80); INSERT EDGE teammate(start_year, end_year) diff --git a/tests/data/nba/like.csv b/tests/data/nba/like.csv index 176b72ccf30..a3108927a89 100644 --- a/tests/data/nba/like.csv +++ b/tests/data/nba/like.csv @@ -53,7 +53,7 @@ Dwyane Wade,Carmelo Anthony,90 Joel Embiid,Ben Simmons,80 Damian Lillard,LaMarcus Aldridge,80 Yao Ming,Tracy McGrady,90 -Yao Ming,Shaquile O'Neal,90 +Yao Ming,Shaquille O'Neal,90 Dejounte Murray,Tim Duncan,99 Dejounte Murray,Tony Parker,99 Dejounte Murray,Manu Ginobili,99 @@ -79,5 +79,5 @@ Dirk Nowitzki,Jason Kidd,80 Dirk Nowitzki,Dwyane Wade,10 Paul George,Russell Westbrook,95 Grant Hill,Tracy McGrady,90 -Shaquile O'Neal,JaVale McGee,100 -Shaquile O'Neal,Tim Duncan,80 +Shaquille O'Neal,JaVale McGee,100 +Shaquille O'Neal,Tim Duncan,80 diff --git a/tests/data/nba/player.csv b/tests/data/nba/player.csv index ba00e2d993b..55d720a2e91 100644 --- a/tests/data/nba/player.csv +++ b/tests/data/nba/player.csv @@ -48,6 +48,6 @@ Jason Kidd,Jason Kidd,45 Dirk Nowitzki,Dirk Nowitzki,40 Paul George,Paul George,28 Grant Hill,Grant Hill,46 -Shaquile O'Neal,Shaquile O'Neal,47 +Shaquille O'Neal,Shaquille O'Neal,47 JaVale McGee,JaVale McGee,31 Dwight Howard,Dwight Howard,33 diff --git a/tests/data/nba/serve.csv b/tests/data/nba/serve.csv index 0dc4308105d..3a1e8a31a36 100644 --- a/tests/data/nba/serve.csv +++ b/tests/data/nba/serve.csv @@ -134,12 +134,12 @@ Grant Hill,Pistons,0,1994,2000 Grant Hill,Magic,0,2000,2007 Grant Hill,Suns,0,2007,2012 Grant Hill,Clippers,0,2012,2013 -Shaquile O'Neal,Magic,0,1992,1996 -Shaquile O'Neal,Lakers,0,1996,2004 -Shaquile O'Neal,Heat,0,2004,2008 -Shaquile O'Neal,Suns,0,2008,2009 -Shaquile O'Neal,Cavaliers,0,2009,2010 -Shaquile O'Neal,Celtics,0,2010,2011 +Shaquille O'Neal,Magic,0,1992,1996 +Shaquille O'Neal,Lakers,0,1996,2004 +Shaquille O'Neal,Heat,0,2004,2008 +Shaquille O'Neal,Suns,0,2008,2009 +Shaquille O'Neal,Cavaliers,0,2009,2010 +Shaquille O'Neal,Celtics,0,2010,2011 JaVale McGee,Wizards,0,2008,2012 JaVale McGee,Nuggets,0,2012,2015 JaVale McGee,Mavericks,0,2015,2016 diff --git a/tests/job/test_session.py b/tests/job/test_session.py index 644536e5b46..19b602a23c6 100644 --- a/tests/job/test_session.py +++ b/tests/job/test_session.py @@ -152,7 +152,7 @@ def get_connection(ip, port): resp = conn1.execute(session_id, 'CREATE SPACE IF NOT EXISTS aSpace(partition_num=1, vid_type=FIXED_STRING(8));USE aSpace;') self.check_resp_succeeded(ResultSet(resp, 0)) - # time::WallClock::fastNowInMicroSec() is not syncronous in different process, + # time::WallClock::fastNowInMicroSec() is not synchronous in different process, # so we sleep 3 seconds here and charge session time.sleep(3) resp = conn1.execute(session_id, 'USE aSpace;') diff --git a/tests/query/stateless/test_update.py b/tests/query/stateless/test_update.py index d7d6bfd7c3c..77e0f37dcfc 100644 --- a/tests/query/stateless/test_update.py +++ b/tests/query/stateless/test_update.py @@ -128,7 +128,7 @@ def test_upsert_vertex(self): self.check_resp_succeeded(resp) self.check_out_of_order_result(resp.rows, expect_result) - # success: oder update, use default value from start + # success: order update, use default value from start cmd = 'UPSERT VERTEX 202 SET person.name = "bb", person.age = $^.person.start + 8, ' \ 'person.start = 10;' resp = self.execute(cmd) @@ -142,7 +142,7 @@ def test_upsert_vertex(self): self.check_resp_succeeded(resp) self.check_out_of_order_result(resp.rows, expect_result) - # success: oder update, use the update value from start + # success: order update, use the update value from start cmd = 'UPSERT VERTEX 202 SET person.name = "bb", person.start = 10, ' \ 'person.age = $^.person.start + 8;' resp = self.execute(cmd) @@ -249,7 +249,7 @@ def test_upsert_edge(self): self.check_resp_succeeded(resp) self.check_out_of_order_result(resp.rows, expect_result) - # success: oder update, use default value from start + # success: order update, use default value from start cmd = 'UPSERT EDGE 204->205 OF study SET name = "bb", start = study.end - 1000, ' \ 'end = 60000;' resp = self.execute(cmd) @@ -263,7 +263,7 @@ def test_upsert_edge(self): self.check_resp_succeeded(resp) self.check_out_of_order_result(resp.rows, expect_result) - # success: oder update, use the update value from start + # success: order update, use the update value from start cmd = 'UPSERT EDGE 206->207 OF study SET end = 60000, start = study.end - 1000' resp = self.execute(cmd) self.check_resp_succeeded(resp) diff --git a/tests/tck/features/bugfix/MatchUsedInPipe.feature b/tests/tck/features/bugfix/MatchUsedInPipe.feature index fcc317eb646..f7d2277f8b2 100644 --- a/tests/tck/features/bugfix/MatchUsedInPipe.feature +++ b/tests/tck/features/bugfix/MatchUsedInPipe.feature @@ -25,7 +25,7 @@ Feature: Test match used in pipe | ("Tim Duncan") | ("Manu Ginobili") | | ("Tim Duncan") | ("Manu Ginobili") | | ("Tim Duncan") | ("Marco Belinelli") | - | ("Tim Duncan") | ("Shaquile O'Neal") | + | ("Tim Duncan") | ("Shaquille O'Neal") | | ("Tim Duncan") | ("Spurs") | | ("Tim Duncan") | ("Tiago Splitter") | | ("Tim Duncan") | ("Tony Parker") | @@ -41,7 +41,7 @@ Feature: Test match used in pipe Then the result should be, in any order, with relax comparison: | $-.n | $-.m | count(*) | | ("Tim Duncan") | ("Spurs") | 1 | - | ("Tim Duncan") | ("Shaquile O'Neal") | 1 | + | ("Tim Duncan") | ("Shaquille O'Neal") | 1 | | ("Tim Duncan") | ("Tiago Splitter") | 1 | | ("Tim Duncan") | ("Marco Belinelli") | 1 | | ("Tim Duncan") | ("Dejounte Murray") | 1 | diff --git a/tests/tck/features/bugfix/SubgraphBeforePipe.feature b/tests/tck/features/bugfix/SubgraphBeforePipe.feature index a4fa4381bb2..c0b66f3419e 100644 --- a/tests/tck/features/bugfix/SubgraphBeforePipe.feature +++ b/tests/tck/features/bugfix/SubgraphBeforePipe.feature @@ -23,7 +23,7 @@ Feature: Test get subgraph before pipe | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | @@ -53,7 +53,7 @@ Feature: Test get subgraph before pipe | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | @@ -89,12 +89,12 @@ Feature: Test get subgraph before pipe | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"LeBron James"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Danny Green"->"Marco Belinelli"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:serve "Danny Green"->"Raptors"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:serve "Danny Green"->"Spurs"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:serve "Manu Ginobili"->"Spurs"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | @@ -107,14 +107,14 @@ Feature: Test get subgraph before pipe | | | [:serve "Boris Diaw"->"Jazz"@0] | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | | [:serve "Boris Diaw"->"Suns"@0] | - | | | [:like "Yao Ming"->"Shaquile O\'Neal"@0] | - | | | [:like "Shaquile O\'Neal"->"JaVale McGee"@0] | - | | | [:serve "Shaquile O\'Neal"->"Cavaliers"@0] | - | | | [:serve "Shaquile O\'Neal"->"Celtics"@0] | - | | | [:serve "Shaquile O\'Neal"->"Heat"@0] | - | | | [:serve "Shaquile O\'Neal"->"Lakers"@0] | - | | | [:serve "Shaquile O\'Neal"->"Magic"@0] | - | | | [:serve "Shaquile O\'Neal"->"Suns"@0] | + | | | [:like "Yao Ming"->"Shaquille O\'Neal"@0] | + | | | [:like "Shaquille O\'Neal"->"JaVale McGee"@0] | + | | | [:serve "Shaquille O\'Neal"->"Cavaliers"@0] | + | | | [:serve "Shaquille O\'Neal"->"Celtics"@0] | + | | | [:serve "Shaquille O\'Neal"->"Heat"@0] | + | | | [:serve "Shaquille O\'Neal"->"Lakers"@0] | + | | | [:serve "Shaquille O\'Neal"->"Magic"@0] | + | | | [:serve "Shaquille O\'Neal"->"Suns"@0] | | | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | | [:like "Marco Belinelli"->"Tony Parker"@0] | @@ -199,7 +199,7 @@ Feature: Test get subgraph before pipe | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | @@ -229,7 +229,7 @@ Feature: Test get subgraph before pipe | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | @@ -254,12 +254,12 @@ Feature: Test get subgraph before pipe | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"LeBron James"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Danny Green"->"Marco Belinelli"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:serve "Danny Green"->"Raptors"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:serve "Danny Green"->"Spurs"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:serve "Manu Ginobili"->"Spurs"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | @@ -272,14 +272,14 @@ Feature: Test get subgraph before pipe | | | [:serve "Boris Diaw"->"Jazz"@0] | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | | [:serve "Boris Diaw"->"Suns"@0] | - | | | [:like "Yao Ming"->"Shaquile O\'Neal"@0] | - | | | [:like "Shaquile O\'Neal"->"JaVale McGee"@0] | - | | | [:serve "Shaquile O\'Neal"->"Cavaliers"@0] | - | | | [:serve "Shaquile O\'Neal"->"Celtics"@0] | - | | | [:serve "Shaquile O\'Neal"->"Heat"@0] | - | | | [:serve "Shaquile O\'Neal"->"Lakers"@0] | - | | | [:serve "Shaquile O\'Neal"->"Magic"@0] | - | | | [:serve "Shaquile O\'Neal"->"Suns"@0] | + | | | [:like "Yao Ming"->"Shaquille O\'Neal"@0] | + | | | [:like "Shaquille O\'Neal"->"JaVale McGee"@0] | + | | | [:serve "Shaquille O\'Neal"->"Cavaliers"@0] | + | | | [:serve "Shaquille O\'Neal"->"Celtics"@0] | + | | | [:serve "Shaquille O\'Neal"->"Heat"@0] | + | | | [:serve "Shaquille O\'Neal"->"Lakers"@0] | + | | | [:serve "Shaquille O\'Neal"->"Magic"@0] | + | | | [:serve "Shaquille O\'Neal"->"Suns"@0] | | | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | | [:like "Marco Belinelli"->"Tony Parker"@0] | diff --git a/tests/tck/features/delete/DeleteVertex.IntVid.feature b/tests/tck/features/delete/DeleteVertex.IntVid.feature index 89f4c6e7753..8843ddede3c 100644 --- a/tests/tck/features/delete/DeleteVertex.IntVid.feature +++ b/tests/tck/features/delete/DeleteVertex.IntVid.feature @@ -196,7 +196,7 @@ Feature: Delete int vid of vertex Then the result should be, in any order: | player.name | player.age | - Scenario: delete int vertex by pipe successed + Scenario: delete int vertex by pipe succeeded Given load "nba_int_vid" csv data to a new space # test delete with pipe wrong vid type When executing query: diff --git a/tests/tck/features/expression/Case.feature b/tests/tck/features/expression/Case.feature index f03f42fbb9d..5bbcddb56aa 100644 --- a/tests/tck/features/expression/Case.feature +++ b/tests/tck/features/expression/Case.feature @@ -153,9 +153,9 @@ Feature: Case Expression RETURN v.name, v.age """ Then the result should be, in any order: - | v.name | v.age | - | "Shaquile O'Neal" | 47 | - | "Grant Hill" | 46 | + | v.name | v.age | + | "Shaquille O'Neal" | 47 | + | "Grant Hill" | 46 | When executing query: """ MATCH (v:player) @@ -163,11 +163,11 @@ Feature: Case Expression RETURN CASE WHEN v.age > 46 THEN v.name WHEN v.age > 45 THEN v.age ELSE "nothing" END AS r """ Then the result should be, in any order: - | r | - | "nothing" | - | 46 | - | "Shaquile O'Neal" | - | "nothing" | + | r | + | "nothing" | + | 46 | + | "Shaquille O'Neal" | + | "nothing" | Scenario: mixed use of generic case and conditional case When executing query: diff --git a/tests/tck/features/expression/FunctionCall.feature b/tests/tck/features/expression/FunctionCall.feature index 5c5a6a00a46..228a65496e9 100644 --- a/tests/tck/features/expression/FunctionCall.feature +++ b/tests/tck/features/expression/FunctionCall.feature @@ -63,8 +63,8 @@ Feature: Function Call Expression RETURN concat(a.name,c.name) """ Then the result should be, in any order: - | concat(a.name,c.name) | - | "Shaquile O'NealLakers" | + | concat(a.name,c.name) | + | "Shaquille O'NealLakers" | When executing query: """ MATCH (a:player)-[b:serve]-(c:team{name: "Lakers"}) @@ -72,8 +72,8 @@ Feature: Function Call Expression RETURN concat(a.name, "hello") """ Then the result should be, in any order: - | concat(a.name,"hello") | - | "Shaquile O'Nealhello" | + | concat(a.name,"hello") | + | "Shaquille O'Nealhello" | Scenario: concat_ws When executing query: @@ -91,8 +91,8 @@ Feature: Function Call Expression RETURN concat_ws("@",a.name, "hello", b.likeness, c.name) as result """ Then the result should be, in any order: - | result | - | "Shaquile O'Neal@hello@Lakers" | + | result | + | "Shaquille O'Neal@hello@Lakers" | When executing query: """ MATCH (a:player)-[b:serve]-(c:team{name: "Lakers"}) @@ -100,8 +100,8 @@ Feature: Function Call Expression RETURN concat_ws("@",a.name, NULL, "hello", b.likeness, c.name) as result """ Then the result should be, in any order: - | result | - | "Shaquile O'Neal@hello@Lakers" | + | result | + | "Shaquille O'Neal@hello@Lakers" | When executing query: """ MATCH (a:player)-[b:serve]-(c:team{name: "Lakers"}) diff --git a/tests/tck/features/expression/Predicate.feature b/tests/tck/features/expression/Predicate.feature index f728c945530..f290f406605 100644 --- a/tests/tck/features/expression/Predicate.feature +++ b/tests/tck/features/expression/Predicate.feature @@ -119,7 +119,7 @@ Feature: Predicate | ("LeBron James" :player{age: 34, name: "LeBron James"}) | | ("Rajon Rondo" :player{age: 33, name: "Rajon Rondo"}) | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | ("Boris Diaw" :player{age: 36, name: "Boris Diaw"}) | | ("Aron Baynes" :player{age: 32, name: "Aron Baynes"}) | | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | @@ -140,7 +140,7 @@ Feature: Predicate MATCH(n:player) WHERE EXISTS("abc") RETURN n.name AS name ORDER BY name LIMIT 10 """ - Then a SyntaxError should be raised at runtime: The exists only accept LabelAttribe, Attribute and Subscript + Then a SyntaxError should be raised at runtime: The exists only accept LabelAttribute, Attribute and Subscript Then drop the used space Scenario: use a exists with null properties diff --git a/tests/tck/features/expression/RelationalExpr.feature b/tests/tck/features/expression/RelationalExpr.feature index 5bae6fe14c8..2215e01c414 100644 --- a/tests/tck/features/expression/RelationalExpr.feature +++ b/tests/tck/features/expression/RelationalExpr.feature @@ -153,7 +153,7 @@ Feature: RelationalExpression | "Rajon Rondo" | 33 | | "Ray Allen" | 43 | | "Rudy Gay" | 32 | - | "Shaquile O'Neal" | 47 | + | "Shaquille O'Neal" | 47 | | "Steve Nash" | 45 | | "Tiago Splitter" | 34 | | "Tim Duncan" | 42 | @@ -196,7 +196,7 @@ Feature: RelationalExpression | "Rajon Rondo" | 33 | | "Ray Allen" | 43 | | "Rudy Gay" | 32 | - | "Shaquile O'Neal" | 47 | + | "Shaquille O'Neal" | 47 | | "Steve Nash" | 45 | | "Tiago Splitter" | 34 | | "Tim Duncan" | 42 | @@ -221,18 +221,15 @@ Feature: RelationalExpression MATCH (v:player) WHERE v.age - 5 >= 40 RETURN v """ Then the result should be, in any order: - | v | - | ("Jason Kidd" :player{age: 45, name: "Jason Kidd"}) | - | ("Grant Hill" :player{age: 46, name: "Grant Hill"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | - | ("Steve Nash" :player{age: 45, name: "Steve Nash"}) | + | v | + | ("Jason Kidd" :player{age: 45, name: "Jason Kidd"}) | + | ("Grant Hill" :player{age: 46, name: "Grant Hill"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | + | ("Steve Nash" :player{age: 45, name: "Steve Nash"}) | And the execution plan should be: - | id | name | dependencies | operator info | - | 10 | Project | 13 | | - | 13 | Filter | 7 | | - | 7 | Project | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 13 | | - | 15 | GetVertices | 11 | | - | 11 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"RANGE"}}} | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 9 | Project | 8 | | + | 8 | Filter | 2 | | + | 2 | AppendVertices | 6 | | + | 6 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"RANGE"}}} | + | 0 | Start | | | diff --git a/tests/tck/features/expression/UnaryExpr.feature b/tests/tck/features/expression/UnaryExpr.feature index b117cfca3fb..591e127e652 100644 --- a/tests/tck/features/expression/UnaryExpr.feature +++ b/tests/tck/features/expression/UnaryExpr.feature @@ -60,7 +60,7 @@ Feature: UnaryExpression | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | | ("Steve Nash" :player{age: 45, name: "Steve Nash"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | ("Ray Allen" :player{age: 43, name: "Ray Allen"}) | | ("Boris Diaw" :player{age: 36, name: "Boris Diaw"}) | | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | @@ -93,14 +93,11 @@ Feature: UnaryExpression | ("Steve Nash" :player{age: 45, name: "Steve Nash"}) | | ("Grant Hill" :player{age: 46, name: "Grant Hill"}) | | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | And the execution plan should be: - | id | name | dependencies | operator info | - | 10 | Project | 12 | | - | 12 | Filter | 7 | | - | 7 | Project | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 14 | | - | 14 | GetVertices | 11 | | - | 11 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"RANGE"}}} | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 9 | Project | 8 | | + | 8 | Filter | 2 | | + | 2 | AppendVertices | 6 | | + | 6 | IndexScan | 0 | | + | 0 | Start | | | diff --git a/tests/tck/features/fetch/FetchVertices.intVid.feature b/tests/tck/features/fetch/FetchVertices.intVid.feature index 8857a319102..f1470ff4cde 100644 --- a/tests/tck/features/fetch/FetchVertices.intVid.feature +++ b/tests/tck/features/fetch/FetchVertices.intVid.feature @@ -330,7 +330,7 @@ Feature: Fetch Int Vid Vertices GO FROM hash('Boris Diaw') over like YIELD like._dst as id, like._dst as id | FETCH PROP ON player $-.id YIELD player.name, player.age """ Then a SemanticError should be raised at runtime: - # only constant list or single colume of data is allowed in piped FETCH clause + # only constant list or single column of data is allowed in piped FETCH clause When executing query: """ GO FROM 'Boris Diaw' over like YIELD like._src as src, like._dst as dst | FETCH PROP ON player $-.src, $-.dst YIELD vertex as node; @@ -411,8 +411,8 @@ Feature: Fetch Int Vid Vertices | "Tim Duncan" | "Tim Duncan" | {age: 42, name: "Tim Duncan"} | When executing query: """ - FETCH PROP ON * hash('Tim Duncan') YIELD id(vertex), keys(vertex) as keys, tags(vertex) as tagss, properties(vertex) as props + FETCH PROP ON * hash('Tim Duncan') YIELD id(vertex), keys(vertex) as keys, tags(vertex) as tags_, properties(vertex) as props """ Then the result should be, in any order, and the columns 0 should be hashed: - | id(VERTEX) | keys | tagss | props | + | id(VERTEX) | keys | tags_ | props | | "Tim Duncan" | ["age", "name", "speciality"] | ["bachelor", "player"] | {age: 42, name: "Tim Duncan", speciality: "psychology"} | diff --git a/tests/tck/features/fetch/FetchVertices.strVid.feature b/tests/tck/features/fetch/FetchVertices.strVid.feature index ed23bf04603..1710050fa56 100644 --- a/tests/tck/features/fetch/FetchVertices.strVid.feature +++ b/tests/tck/features/fetch/FetchVertices.strVid.feature @@ -272,7 +272,7 @@ Feature: Fetch String Vertices | "Tony Parker" | 36 | EMPTY | EMPTY | EMPTY | | "Tim Duncan" | 42 | EMPTY | "Tim Duncan" | "psychology" | - Scenario: fetch from varibles + Scenario: fetch from variables When executing query: """ $var = GO FROM 'Boris Diaw' over like YIELD like._dst as id; FETCH PROP ON player $var.id YIELD player.name, player.age @@ -331,11 +331,11 @@ Feature: Fetch String Vertices FETCH PROP ON player "Tim Duncan", "Yao Ming" YIELD vertex as node | go from id($-.node) over like yield like._dst """ Then the result should be, in any order: - | like._dst | - | "Shaquile O'Neal" | - | "Tracy McGrady" | - | "Manu Ginobili" | - | "Tony Parker" | + | like._dst | + | "Shaquille O'Neal" | + | "Tracy McGrady" | + | "Manu Ginobili" | + | "Tony Parker" | When executing query: """ FETCH PROP ON player "Tim Duncan" yield player.name as id | go from $-.id over like yield like._dst @@ -349,11 +349,11 @@ Feature: Fetch String Vertices $var = FETCH PROP ON player "Tim Duncan", "Yao Ming"; go from id($var.vertices_) over like yield like._dst """ Then the result should be, in any order: - | like._dst | - | "Manu Ginobili" | - | "Tony Parker" | - | "Shaquile O'Neal" | - | "Tracy McGrady" | + | like._dst | + | "Manu Ginobili" | + | "Tony Parker" | + | "Shaquille O'Neal" | + | "Tracy McGrady" | When executing query: """ FETCH PROP ON player 'Tony Parker' YIELD player.name as Name | @@ -441,7 +441,7 @@ Feature: Fetch String Vertices FETCH PROP ON * "Tim Duncan", "Boris Diaw" YIELD player.not_exist_prop """ Then a SemanticError should be raised at runtime: - # only constant list or single colume of data is allowed in piped FETCH clause + # only constant list or single column of data is allowed in piped FETCH clause When executing query: """ GO FROM 'Boris Diaw' over like YIELD like._src as src, like._dst as dst | FETCH PROP ON player $-.src, $-.dst; @@ -522,8 +522,8 @@ Feature: Fetch String Vertices | "Tim Duncan" | "Tim Duncan" | {age: 42, name: "Tim Duncan"} | When executing query: """ - FETCH PROP ON * 'Tim Duncan' YIELD id(vertex), keys(vertex) as keys, tags(vertex) as tagss, properties(vertex) as props + FETCH PROP ON * 'Tim Duncan' YIELD id(vertex), keys(vertex) as keys, tags(vertex) as tags_, properties(vertex) as props """ Then the result should be, in any order: - | id(VERTEX) | keys | tagss | props | + | id(VERTEX) | keys | tags_ | props | | "Tim Duncan" | ["age", "name", "speciality"] | ["bachelor", "player"] | {age: 42, name: "Tim Duncan", speciality: "psychology"} | diff --git a/tests/tck/features/geo/GeoBase.feature b/tests/tck/features/geo/GeoBase.feature index 0e0a33335bd..24983b3e051 100644 --- a/tests/tck/features/geo/GeoBase.feature +++ b/tests/tck/features/geo/GeoBase.feature @@ -81,12 +81,12 @@ Feature: Geo base """ CREATE EDGE test_2(geo geography DEFAULT ST_GeogFromText("LINESTRING(0 1, 2xxxx")); """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! When executing query: """ CREATE TAG test_3(geo geography(point) DEFAULT ST_GeogFromText("LineString(0 1, 2 3)")); """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! When executing query: """ CREATE TAG test_3(geo geography(linestring) DEFAULT ST_GeogFromText("LineString(0 1, 2 3)")); @@ -349,7 +349,7 @@ Feature: Geo base INSERT EDGE any_shape_edge(geo) VALUES "108"->"408":(ST_GeogFromText("POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (1.0 1.0, 2.0 2.0, 0.0 2.0, 1.0 1.0))")); """ Then the execution should be successful - # Lookup on geo index agagin + # Lookup on geo index again When executing query: """ LOOKUP ON any_shape YIELD ST_ASText(any_shape.geo); diff --git a/tests/tck/features/go/GO.IntVid.feature b/tests/tck/features/go/GO.IntVid.feature index 8eeecc95b18..2dd3b6d20f3 100644 --- a/tests/tck/features/go/GO.IntVid.feature +++ b/tests/tck/features/go/GO.IntVid.feature @@ -376,7 +376,7 @@ Feature: IntegerVid Go Sentence | EMPTY | 90 | When executing query: """ - GO FROM hash("Shaquile O\'Neal") OVER serve, like YIELD serve._dst, like._dst + GO FROM hash("Shaquille O\'Neal") OVER serve, like YIELD serve._dst, like._dst """ Then the result should be, in any order, with relax comparison, and the columns 0,1 should be hashed: | serve._dst | like._dst | @@ -726,7 +726,7 @@ Feature: IntegerVid Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | When executing query: """ GO FROM hash('Tim Duncan') OVER like REVERSELY YIELD $$.player.name @@ -742,7 +742,7 @@ Feature: IntegerVid Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | When executing query: """ GO FROM hash('Tim Duncan') OVER like REVERSELY WHERE $$.player.age < 35 YIELD $$.player.name @@ -770,7 +770,7 @@ Feature: IntegerVid Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | EMPTY | | EMPTY | @@ -859,15 +859,15 @@ Feature: IntegerVid Go Sentence | "Cavaliers" | "Kyrie Irving" | | "Cavaliers" | "LeBron James" | | "Cavaliers" | "LeBron James" | - | "Cavaliers" | "Shaquile O'Neal" | - | "Cavaliers" | "Shaquile O'Neal" | + | "Cavaliers" | "Shaquille O'Neal" | + | "Cavaliers" | "Shaquille O'Neal" | | "Cavaliers" | "LeBron James" | | "Cavaliers" | "LeBron James" | | "Heat" | "Amar'e Stoudemire" | | "Heat" | "Dwyane Wade" | | "Heat" | "LeBron James" | | "Heat" | "Ray Allen" | - | "Heat" | "Shaquile O'Neal" | + | "Heat" | "Shaquille O'Neal" | | "Heat" | "Dwyane Wade" | | "Lakers" | "Dwight Howard" | | "Lakers" | "JaVale McGee" | @@ -875,7 +875,7 @@ Feature: IntegerVid Go Sentence | "Lakers" | "LeBron James" | | "Lakers" | "Paul Gasol" | | "Lakers" | "Rajon Rondo" | - | "Lakers" | "Shaquile O'Neal" | + | "Lakers" | "Shaquille O'Neal" | | "Lakers" | "Steve Nash" | When executing query: """ @@ -891,19 +891,19 @@ Feature: IntegerVid Go Sentence | "Cavaliers" | "Dwyane Wade" | | "Cavaliers" | "Kyrie Irving" | | "Cavaliers" | "Kyrie Irving" | - | "Cavaliers" | "Shaquile O'Neal" | - | "Cavaliers" | "Shaquile O'Neal" | + | "Cavaliers" | "Shaquille O'Neal" | + | "Cavaliers" | "Shaquille O'Neal" | | "Heat" | "Amar'e Stoudemire" | | "Heat" | "Dwyane Wade" | | "Heat" | "Ray Allen" | - | "Heat" | "Shaquile O'Neal" | + | "Heat" | "Shaquille O'Neal" | | "Heat" | "Dwyane Wade" | | "Lakers" | "Dwight Howard" | | "Lakers" | "JaVale McGee" | | "Lakers" | "Kobe Bryant" | | "Lakers" | "Paul Gasol" | | "Lakers" | "Rajon Rondo" | - | "Lakers" | "Shaquile O'Neal" | + | "Lakers" | "Shaquille O'Neal" | | "Lakers" | "Steve Nash" | When executing query: """ @@ -945,7 +945,7 @@ Feature: IntegerVid Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | When executing query: """ GO FROM hash('Tim Duncan') OVER serve, like bidirect YIELD serve._dst, like._dst @@ -964,7 +964,7 @@ Feature: IntegerVid Go Sentence | EMPTY | "Boris Diaw" | | EMPTY | "Tiago Splitter" | | EMPTY | "Dejounte Murray" | - | EMPTY | "Shaquile O'Neal" | + | EMPTY | "Shaquille O'Neal" | When executing query: """ GO FROM hash('Tim Duncan') OVER serve bidirect YIELD $$.team.name @@ -989,7 +989,7 @@ Feature: IntegerVid Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | When executing query: """ GO FROM hash('Tim Duncan') OVER like bidirect WHERE like.likeness > 90 @@ -1021,7 +1021,7 @@ Feature: IntegerVid Go Sentence | "Tim Duncan" | EMPTY | EMPTY | "Boris Diaw" | "Boris Diaw" | | "Tim Duncan" | EMPTY | EMPTY | "Tiago Splitter" | "Tiago Splitter" | | "Tim Duncan" | EMPTY | EMPTY | "Dejounte Murray" | "Dejounte Murray" | - | "Tim Duncan" | EMPTY | EMPTY | "Shaquile O'Neal" | "Shaquile O'Neal" | + | "Tim Duncan" | EMPTY | EMPTY | "Shaquille O'Neal" | "Shaquille O'Neal" | | "Tim Duncan" | EMPTY | EMPTY | EMPTY | "Tony Parker" | | "Tim Duncan" | EMPTY | EMPTY | EMPTY | "Manu Ginobili" | | "Tim Duncan" | EMPTY | EMPTY | EMPTY | "Danny Green" | @@ -1046,7 +1046,7 @@ Feature: IntegerVid Go Sentence | "Boris Diaw" | EMPTY | EMPTY | | "Tiago Splitter" | EMPTY | EMPTY | | "Dejounte Murray" | EMPTY | EMPTY | - | "Shaquile O'Neal" | EMPTY | EMPTY | + | "Shaquille O'Neal" | EMPTY | EMPTY | | EMPTY | EMPTY | "Tony Parker" | | EMPTY | EMPTY | "Manu Ginobili" | | EMPTY | EMPTY | "LaMarcus Aldridge" | @@ -1208,7 +1208,7 @@ Feature: IntegerVid Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | When executing query: @@ -1227,7 +1227,7 @@ Feature: IntegerVid Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | When executing query: @@ -1245,7 +1245,7 @@ Feature: IntegerVid Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | When executing query: @@ -1312,7 +1312,7 @@ Feature: IntegerVid Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | | "LeBron James" | @@ -1337,7 +1337,7 @@ Feature: IntegerVid Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | | "LeBron James" | diff --git a/tests/tck/features/go/GO.feature b/tests/tck/features/go/GO.feature index de2219d4965..7878a3f9017 100644 --- a/tests/tck/features/go/GO.feature +++ b/tests/tck/features/go/GO.feature @@ -425,7 +425,7 @@ Feature: Go Sentence | EMPTY | 90 | When executing query: """ - GO FROM "Shaquile O\'Neal" OVER serve, like YIELD serve._dst, like._dst + GO FROM "Shaquille O\'Neal" OVER serve, like YIELD serve._dst, like._dst """ Then the result should be, in any order, with relax comparison: | serve._dst | like._dst | @@ -775,7 +775,7 @@ Feature: Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | When executing query: """ GO FROM 'Tim Duncan' OVER like REVERSELY YIELD $$.player.name @@ -791,7 +791,7 @@ Feature: Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | When executing query: """ GO FROM 'Tim Duncan' OVER like REVERSELY WHERE $$.player.age < 35 YIELD $$.player.name @@ -819,7 +819,7 @@ Feature: Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | EMPTY | | EMPTY | @@ -908,15 +908,15 @@ Feature: Go Sentence | "Cavaliers" | "Kyrie Irving" | | "Cavaliers" | "LeBron James" | | "Cavaliers" | "LeBron James" | - | "Cavaliers" | "Shaquile O'Neal" | - | "Cavaliers" | "Shaquile O'Neal" | + | "Cavaliers" | "Shaquille O'Neal" | + | "Cavaliers" | "Shaquille O'Neal" | | "Cavaliers" | "LeBron James" | | "Cavaliers" | "LeBron James" | | "Heat" | "Amar'e Stoudemire" | | "Heat" | "Dwyane Wade" | | "Heat" | "LeBron James" | | "Heat" | "Ray Allen" | - | "Heat" | "Shaquile O'Neal" | + | "Heat" | "Shaquille O'Neal" | | "Heat" | "Dwyane Wade" | | "Lakers" | "Dwight Howard" | | "Lakers" | "JaVale McGee" | @@ -924,7 +924,7 @@ Feature: Go Sentence | "Lakers" | "LeBron James" | | "Lakers" | "Paul Gasol" | | "Lakers" | "Rajon Rondo" | - | "Lakers" | "Shaquile O'Neal" | + | "Lakers" | "Shaquille O'Neal" | | "Lakers" | "Steve Nash" | When executing query: """ @@ -940,19 +940,19 @@ Feature: Go Sentence | "Cavaliers" | "Dwyane Wade" | | "Cavaliers" | "Kyrie Irving" | | "Cavaliers" | "Kyrie Irving" | - | "Cavaliers" | "Shaquile O'Neal" | - | "Cavaliers" | "Shaquile O'Neal" | + | "Cavaliers" | "Shaquille O'Neal" | + | "Cavaliers" | "Shaquille O'Neal" | | "Heat" | "Amar'e Stoudemire" | | "Heat" | "Dwyane Wade" | | "Heat" | "Ray Allen" | - | "Heat" | "Shaquile O'Neal" | + | "Heat" | "Shaquille O'Neal" | | "Heat" | "Dwyane Wade" | | "Lakers" | "Dwight Howard" | | "Lakers" | "JaVale McGee" | | "Lakers" | "Kobe Bryant" | | "Lakers" | "Paul Gasol" | | "Lakers" | "Rajon Rondo" | - | "Lakers" | "Shaquile O'Neal" | + | "Lakers" | "Shaquille O'Neal" | | "Lakers" | "Steve Nash" | When executing query: """ @@ -994,7 +994,7 @@ Feature: Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | When executing query: """ GO FROM 'Tim Duncan' OVER serve, like bidirect YIELD serve._dst, like._dst @@ -1013,7 +1013,7 @@ Feature: Go Sentence | EMPTY | "Boris Diaw" | | EMPTY | "Tiago Splitter" | | EMPTY | "Dejounte Murray" | - | EMPTY | "Shaquile O'Neal" | + | EMPTY | "Shaquille O'Neal" | When executing query: """ GO FROM 'Tim Duncan' OVER serve bidirect YIELD $$.team.name @@ -1038,7 +1038,7 @@ Feature: Go Sentence | "Boris Diaw" | | "Tiago Splitter" | | "Dejounte Murray" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | When executing query: """ GO FROM 'Tim Duncan' OVER like bidirect WHERE like.likeness > 90 @@ -1070,7 +1070,7 @@ Feature: Go Sentence | "Tim Duncan" | EMPTY | EMPTY | "Boris Diaw" | "Boris Diaw" | | "Tim Duncan" | EMPTY | EMPTY | "Tiago Splitter" | "Tiago Splitter" | | "Tim Duncan" | EMPTY | EMPTY | "Dejounte Murray" | "Dejounte Murray" | - | "Tim Duncan" | EMPTY | EMPTY | "Shaquile O'Neal" | "Shaquile O'Neal" | + | "Tim Duncan" | EMPTY | EMPTY | "Shaquille O'Neal" | "Shaquille O'Neal" | | "Tim Duncan" | EMPTY | EMPTY | EMPTY | "Tony Parker" | | "Tim Duncan" | EMPTY | EMPTY | EMPTY | "Manu Ginobili" | | "Tim Duncan" | EMPTY | EMPTY | EMPTY | "Danny Green" | @@ -1095,7 +1095,7 @@ Feature: Go Sentence | "Boris Diaw" | EMPTY | EMPTY | | "Tiago Splitter" | EMPTY | EMPTY | | "Dejounte Murray" | EMPTY | EMPTY | - | "Shaquile O'Neal" | EMPTY | EMPTY | + | "Shaquille O'Neal" | EMPTY | EMPTY | | EMPTY | EMPTY | "Tony Parker" | | EMPTY | EMPTY | "Manu Ginobili" | | EMPTY | EMPTY | "LaMarcus Aldridge" | @@ -1264,7 +1264,7 @@ Feature: Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | When executing query: @@ -1283,7 +1283,7 @@ Feature: Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | When executing query: @@ -1301,7 +1301,7 @@ Feature: Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | When executing query: @@ -1368,7 +1368,7 @@ Feature: Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | | "LeBron James" | @@ -1393,7 +1393,7 @@ Feature: Go Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | | "LeBron James" | diff --git a/tests/tck/features/go/GoYieldVertexEdge.feature b/tests/tck/features/go/GoYieldVertexEdge.feature index 6bcdadf491a..81b0e8c1129 100644 --- a/tests/tck/features/go/GoYieldVertexEdge.feature +++ b/tests/tck/features/go/GoYieldVertexEdge.feature @@ -426,7 +426,7 @@ Feature: Go Yield Vertex And Edge Sentence | {likeness: 90} | "like" | When executing query: """ - GO FROM "Shaquile O\'Neal" OVER serve, like YIELD dst(edge) as dst + GO FROM "Shaquille O\'Neal" OVER serve, like YIELD dst(edge) as dst """ Then the result should be, in any order, with relax comparison: | dst | @@ -706,7 +706,7 @@ Feature: Go Yield Vertex And Edge Sentence | ("LaMarcus Aldridge" :player{age: 33, name: "LaMarcus Aldridge"}) | [:like "LaMarcus Aldridge"->"Tim Duncan" @0 {likeness: 75}] | | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | [:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}] | | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | [:like "Marco Belinelli"->"Tim Duncan" @0 {likeness: 55}] | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | [:like "Shaquile O'Neal"->"Tim Duncan" @0 {likeness: 80}] | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | [:like "Shaquille O'Neal"->"Tim Duncan" @0 {likeness: 80}] | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | [:like "Tiago Splitter"->"Tim Duncan" @0 {likeness: 80}] | | ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | When executing query: @@ -722,7 +722,7 @@ Feature: Go Yield Vertex And Edge Sentence | ("LaMarcus Aldridge" :player{age: 33, name: "LaMarcus Aldridge"}) | [:like "LaMarcus Aldridge"->"Tim Duncan" @0 {likeness: 75}] | "LaMarcus Aldridge" | "Tim Duncan" | | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | [:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}] | "Manu Ginobili" | "Tim Duncan" | | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | [:like "Marco Belinelli"->"Tim Duncan" @0 {likeness: 55}] | "Marco Belinelli" | "Tim Duncan" | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | [:like "Shaquile O'Neal"->"Tim Duncan" @0 {likeness: 80}] | "Shaquile O'Neal" | "Tim Duncan" | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | [:like "Shaquille O'Neal"->"Tim Duncan" @0 {likeness: 80}] | "Shaquille O'Neal" | "Tim Duncan" | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | [:like "Tiago Splitter"->"Tim Duncan" @0 {likeness: 80}] | "Tiago Splitter" | "Tim Duncan" | | ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | "Tony Parker" | "Tim Duncan" | When executing query: @@ -887,7 +887,7 @@ Feature: Go Yield Vertex And Edge Sentence | ("Heat" :team{name: "Heat"}) | ("Dwyane Wade" :player{age: 37, name: "Dwyane Wade"}) | | ("Heat" :team{name: "Heat"}) | ("LeBron James" :player{age: 34, name: "LeBron James"}) | | ("Heat" :team{name: "Heat"}) | ("Ray Allen" :player{age: 43, name: "Ray Allen"}) | - | ("Heat" :team{name: "Heat"}) | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Heat" :team{name: "Heat"}) | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | ("Heat" :team{name: "Heat"}) | ("Dwyane Wade" :player{age: 37, name: "Dwyane Wade"}) | | ("Lakers" :team{name: "Lakers"}) | ("Dwight Howard" :player{age: 33, name: "Dwight Howard"}) | | ("Lakers" :team{name: "Lakers"}) | ("JaVale McGee" :player{age: 31, name: "JaVale McGee"}) | @@ -895,7 +895,7 @@ Feature: Go Yield Vertex And Edge Sentence | ("Lakers" :team{name: "Lakers"}) | ("LeBron James" :player{age: 34, name: "LeBron James"}) | | ("Lakers" :team{name: "Lakers"}) | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | | ("Lakers" :team{name: "Lakers"}) | ("Rajon Rondo" :player{age: 33, name: "Rajon Rondo"}) | - | ("Lakers" :team{name: "Lakers"}) | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Lakers" :team{name: "Lakers"}) | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | ("Lakers" :team{name: "Lakers"}) | ("Steve Nash" :player{age: 45, name: "Steve Nash"}) | | ("Cavaliers" :team{name: "Cavaliers"}) | ("Danny Green" :player{age: 31, name: "Danny Green"}) | | ("Cavaliers" :team{name: "Cavaliers"}) | ("Danny Green" :player{age: 31, name: "Danny Green"}) | @@ -905,8 +905,8 @@ Feature: Go Yield Vertex And Edge Sentence | ("Cavaliers" :team{name: "Cavaliers"}) | ("Kyrie Irving" :player{age: 26, name: "Kyrie Irving"}) | | ("Cavaliers" :team{name: "Cavaliers"}) | ("LeBron James" :player{age: 34, name: "LeBron James"}) | | ("Cavaliers" :team{name: "Cavaliers"}) | ("LeBron James" :player{age: 34, name: "LeBron James"}) | - | ("Cavaliers" :team{name: "Cavaliers"}) | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | - | ("Cavaliers" :team{name: "Cavaliers"}) | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Cavaliers" :team{name: "Cavaliers"}) | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | + | ("Cavaliers" :team{name: "Cavaliers"}) | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | ("Cavaliers" :team{name: "Cavaliers"}) | ("LeBron James" :player{age: 34, name: "LeBron James"}) | | ("Cavaliers" :team{name: "Cavaliers"}) | ("LeBron James" :player{age: 34, name: "LeBron James"}) | When executing query: @@ -916,23 +916,23 @@ Feature: Go Yield Vertex And Edge Sentence YIELD distinct edge as e """ Then the result should be, in any order, with relax comparison: - | e | - | [:serve "Amar'e Stoudemire"->"Heat" @0 {end_year: 2016, start_year: 2015}] | - | [:serve "Dwyane Wade"->"Heat" @0 {end_year: 2016, start_year: 2003}] | - | [:serve "Shaquile O'Neal"->"Cavaliers" @0 {end_year: 2010, start_year: 2009}] | - | [:serve "Ray Allen"->"Heat" @0 {end_year: 2014, start_year: 2012}] | - | [:serve "Shaquile O'Neal"->"Heat" @0 {end_year: 2008, start_year: 2004}] | - | [:serve "Dwyane Wade"->"Heat" @1 {end_year: 2019, start_year: 2018}] | - | [:serve "Dwight Howard"->"Lakers" @0 {end_year: 2013, start_year: 2012}] | - | [:serve "JaVale McGee"->"Lakers" @0 {end_year: 2019, start_year: 2018}] | - | [:serve "Kobe Bryant"->"Lakers" @0 {end_year: 2016, start_year: 1996}] | - | [:serve "Kyrie Irving"->"Cavaliers" @0 {end_year: 2017, start_year: 2011}] | - | [:serve "Paul Gasol"->"Lakers" @0 {end_year: 2014, start_year: 2008}] | - | [:serve "Rajon Rondo"->"Lakers" @0 {end_year: 2019, start_year: 2018}] | - | [:serve "Shaquile O'Neal"->"Lakers" @0 {end_year: 2004, start_year: 1996}] | - | [:serve "Steve Nash"->"Lakers" @0 {end_year: 2015, start_year: 2012}] | - | [:serve "Danny Green"->"Cavaliers" @0 {end_year: 2010, start_year: 2009}] | - | [:serve "Dwyane Wade"->"Cavaliers" @0 {end_year: 2018, start_year: 2017}] | + | e | + | [:serve "Amar'e Stoudemire"->"Heat" @0 {end_year: 2016, start_year: 2015}] | + | [:serve "Dwyane Wade"->"Heat" @0 {end_year: 2016, start_year: 2003}] | + | [:serve "Shaquille O'Neal"->"Cavaliers" @0 {end_year: 2010, start_year: 2009}] | + | [:serve "Ray Allen"->"Heat" @0 {end_year: 2014, start_year: 2012}] | + | [:serve "Shaquille O'Neal"->"Heat" @0 {end_year: 2008, start_year: 2004}] | + | [:serve "Dwyane Wade"->"Heat" @1 {end_year: 2019, start_year: 2018}] | + | [:serve "Dwight Howard"->"Lakers" @0 {end_year: 2013, start_year: 2012}] | + | [:serve "JaVale McGee"->"Lakers" @0 {end_year: 2019, start_year: 2018}] | + | [:serve "Kobe Bryant"->"Lakers" @0 {end_year: 2016, start_year: 1996}] | + | [:serve "Kyrie Irving"->"Cavaliers" @0 {end_year: 2017, start_year: 2011}] | + | [:serve "Paul Gasol"->"Lakers" @0 {end_year: 2014, start_year: 2008}] | + | [:serve "Rajon Rondo"->"Lakers" @0 {end_year: 2019, start_year: 2018}] | + | [:serve "Shaquille O'Neal"->"Lakers" @0 {end_year: 2004, start_year: 1996}] | + | [:serve "Steve Nash"->"Lakers" @0 {end_year: 2015, start_year: 2012}] | + | [:serve "Danny Green"->"Cavaliers" @0 {end_year: 2010, start_year: 2009}] | + | [:serve "Dwyane Wade"->"Cavaliers" @0 {end_year: 2018, start_year: 2017}] | When executing query: """ GO FROM 'Manu Ginobili' OVER like REVERSELY YIELD src(edge) AS id | @@ -966,7 +966,7 @@ Feature: Go Yield Vertex And Edge Sentence | [:like "LaMarcus Aldridge"->"Tim Duncan" @0 {likeness: 75}] | | [:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}] | | [:like "Marco Belinelli"->"Tim Duncan" @0 {likeness: 55}] | - | [:like "Shaquile O'Neal"->"Tim Duncan" @0 {likeness: 80}] | + | [:like "Shaquille O'Neal"->"Tim Duncan" @0 {likeness: 80}] | | [:like "Tiago Splitter"->"Tim Duncan" @0 {likeness: 80}] | | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | | [:like "Tim Duncan"->"Manu Ginobili" @0 {likeness: 95}] | @@ -994,7 +994,7 @@ Feature: Go Yield Vertex And Edge Sentence | ("LaMarcus Aldridge" :player{age: 33, name: "LaMarcus Aldridge"}) | | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | | ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | @@ -1024,7 +1024,7 @@ Feature: Go Yield Vertex And Edge Sentence | [:like "LaMarcus Aldridge"->"Tim Duncan" @0 {likeness: 75}] | | [:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}] | | [:like "Marco Belinelli"->"Tim Duncan" @0 {likeness: 55}] | - | [:like "Shaquile O'Neal"->"Tim Duncan" @0 {likeness: 80}] | + | [:like "Shaquille O'Neal"->"Tim Duncan" @0 {likeness: 80}] | | [:like "Tiago Splitter"->"Tim Duncan" @0 {likeness: 80}] | | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | | [:teammate "Manu Ginobili"->"Tim Duncan" @0 {end_year: 2016, start_year: 2002}] | @@ -1212,7 +1212,7 @@ Feature: Go Yield Vertex And Edge Sentence | "Danny Green" | | "Aron Baynes" | | "Tiago Splitter" | - | "Shaquile O'Neal" | + | "Shaquille O'Neal" | | "Rudy Gay" | | "Damian Lillard" | When executing query: @@ -1236,7 +1236,7 @@ Feature: Go Yield Vertex And Edge Sentence | [:like "LaMarcus Aldridge"->"Tim Duncan" @0 {likeness: 75}] | | [:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}] | | [:like "Marco Belinelli"->"Tim Duncan" @0 {likeness: 55}] | - | [:like "Shaquile O'Neal"->"Tim Duncan" @0 {likeness: 80}] | + | [:like "Shaquille O'Neal"->"Tim Duncan" @0 {likeness: 80}] | | [:like "Tiago Splitter"->"Tim Duncan" @0 {likeness: 80}] | | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | | [:like "Danny Green"->"Marco Belinelli" @0 {likeness: 83}] | @@ -1257,7 +1257,7 @@ Feature: Go Yield Vertex And Edge Sentence | ("LaMarcus Aldridge" :player{age: 33, name: "LaMarcus Aldridge"}) | | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | When executing query: """ @@ -1333,7 +1333,7 @@ Feature: Go Yield Vertex And Edge Sentence | "LaMarcus Aldridge" | "Tim Duncan" | | "Manu Ginobili" | "Tim Duncan" | | "Dejounte Murray" | "LeBron James" | - | "Shaquile O'Neal" | "Tim Duncan" | + | "Shaquille O'Neal" | "Tim Duncan" | | "Tiago Splitter" | "Tim Duncan" | | "Dejounte Murray" | "Kyle Anderson" | | "Tim Duncan" | "Manu Ginobili" | diff --git a/tests/tck/features/insert/Insert.IntVid.feature b/tests/tck/features/insert/Insert.IntVid.feature index 520e24ea01e..1ee3326fa2e 100644 --- a/tests/tck/features/insert/Insert.IntVid.feature +++ b/tests/tck/features/insert/Insert.IntVid.feature @@ -30,7 +30,7 @@ Feature: Insert int vid of vertex and edge Scenario: insert vertex and edge test Given wait 3 seconds - # insert vretex with default property names + # insert vertex with default property names When try to execute query: """ INSERT VERTEX person VALUES hash("Tom"):("Tom", 18); diff --git a/tests/tck/features/insert/Insert.feature b/tests/tck/features/insert/Insert.feature index 38157303e0f..884de390357 100644 --- a/tests/tck/features/insert/Insert.feature +++ b/tests/tck/features/insert/Insert.feature @@ -33,7 +33,7 @@ Feature: Insert string vid of vertex and edge INSERT VERTEX person(name, age) VALUES "Tom":("Tom", 22) """ Then the execution should be successful - # insert vretex with default property names + # insert vertex with default property names When executing query: """ INSERT VERTEX person VALUES "Tom":("Tom", 18); diff --git a/tests/tck/features/lookup/ByIndex.feature b/tests/tck/features/lookup/ByIndex.feature index 357f66b5894..d6df792509c 100644 --- a/tests/tck/features/lookup/ByIndex.feature +++ b/tests/tck/features/lookup/ByIndex.feature @@ -244,12 +244,12 @@ Feature: Lookup by index itself | 'Grant Hill' | 'Magic' | 0 | | 'Grant Hill' | 'Suns' | 0 | | 'Grant Hill' | 'Clippers' | 0 | - | "Shaquile O'Neal" | 'Magic' | 0 | - | "Shaquile O'Neal" | 'Lakers' | 0 | - | "Shaquile O'Neal" | 'Heat' | 0 | - | "Shaquile O'Neal" | 'Suns' | 0 | - | "Shaquile O'Neal" | 'Cavaliers' | 0 | - | "Shaquile O'Neal" | 'Celtics' | 0 | + | "Shaquille O'Neal" | 'Magic' | 0 | + | "Shaquille O'Neal" | 'Lakers' | 0 | + | "Shaquille O'Neal" | 'Heat' | 0 | + | "Shaquille O'Neal" | 'Suns' | 0 | + | "Shaquille O'Neal" | 'Cavaliers' | 0 | + | "Shaquille O'Neal" | 'Celtics' | 0 | | 'JaVale McGee' | 'Wizards' | 0 | | 'JaVale McGee' | 'Nuggets' | 0 | | 'JaVale McGee' | 'Mavericks' | 0 | @@ -402,12 +402,12 @@ Feature: Lookup by index itself | 'Grant Hill' | 'Magic' | 0 | 2000 | | 'Grant Hill' | 'Suns' | 0 | 2007 | | 'Grant Hill' | 'Clippers' | 0 | 2012 | - | "Shaquile O'Neal" | 'Magic' | 0 | 1992 | - | "Shaquile O'Neal" | 'Lakers' | 0 | 1996 | - | "Shaquile O'Neal" | 'Heat' | 0 | 2004 | - | "Shaquile O'Neal" | 'Suns' | 0 | 2008 | - | "Shaquile O'Neal" | 'Cavaliers' | 0 | 2009 | - | "Shaquile O'Neal" | 'Celtics' | 0 | 2010 | + | "Shaquille O'Neal" | 'Magic' | 0 | 1992 | + | "Shaquille O'Neal" | 'Lakers' | 0 | 1996 | + | "Shaquille O'Neal" | 'Heat' | 0 | 2004 | + | "Shaquille O'Neal" | 'Suns' | 0 | 2008 | + | "Shaquille O'Neal" | 'Cavaliers' | 0 | 2009 | + | "Shaquille O'Neal" | 'Celtics' | 0 | 2010 | | 'JaVale McGee' | 'Wizards' | 0 | 2008 | | 'JaVale McGee' | 'Nuggets' | 0 | 2012 | | 'JaVale McGee' | 'Mavericks' | 0 | 2015 | @@ -458,59 +458,59 @@ Feature: Lookup by index itself LOOKUP ON player WHERE player.age > 40 YIELD player.age AS Age """ Then the result should be, in any order: - | VertexID | Age | - | "Grant Hill" | 46 | - | "Jason Kidd" | 45 | - | "Manu Ginobili" | 41 | - | "Ray Allen" | 43 | - | "Shaquile O'Neal" | 47 | - | "Steve Nash" | 45 | - | "Tim Duncan" | 42 | - | "Vince Carter" | 42 | + | VertexID | Age | + | "Grant Hill" | 46 | + | "Jason Kidd" | 45 | + | "Manu Ginobili" | 41 | + | "Ray Allen" | 43 | + | "Shaquille O'Neal" | 47 | + | "Steve Nash" | 45 | + | "Tim Duncan" | 42 | + | "Vince Carter" | 42 | When executing query: """ LOOKUP ON player WHERE player.age >= 40.0 YIELD player.age AS Age """ Then the result should be, in any order: - | VertexID | Age | - | "Grant Hill" | 46 | - | "Jason Kidd" | 45 | - | "Manu Ginobili" | 41 | - | "Ray Allen" | 43 | - | "Shaquile O'Neal" | 47 | - | "Steve Nash" | 45 | - | "Tim Duncan" | 42 | - | "Vince Carter" | 42 | - | "Dirk Nowitzki" | 40 | - | "Kobe Bryant" | 40 | + | VertexID | Age | + | "Grant Hill" | 46 | + | "Jason Kidd" | 45 | + | "Manu Ginobili" | 41 | + | "Ray Allen" | 43 | + | "Shaquille O'Neal" | 47 | + | "Steve Nash" | 45 | + | "Tim Duncan" | 42 | + | "Vince Carter" | 42 | + | "Dirk Nowitzki" | 40 | + | "Kobe Bryant" | 40 | When executing query: """ LOOKUP ON player WHERE player.age > 40.5 YIELD player.age AS Age """ Then the result should be, in any order: - | VertexID | Age | - | "Grant Hill" | 46 | - | "Jason Kidd" | 45 | - | "Manu Ginobili" | 41 | - | "Ray Allen" | 43 | - | "Shaquile O'Neal" | 47 | - | "Steve Nash" | 45 | - | "Tim Duncan" | 42 | - | "Vince Carter" | 42 | + | VertexID | Age | + | "Grant Hill" | 46 | + | "Jason Kidd" | 45 | + | "Manu Ginobili" | 41 | + | "Ray Allen" | 43 | + | "Shaquille O'Neal" | 47 | + | "Steve Nash" | 45 | + | "Tim Duncan" | 42 | + | "Vince Carter" | 42 | When executing query: """ LOOKUP ON player WHERE player.age >= 40.5 YIELD player.age AS Age """ Then the result should be, in any order: - | VertexID | Age | - | "Grant Hill" | 46 | - | "Jason Kidd" | 45 | - | "Manu Ginobili" | 41 | - | "Ray Allen" | 43 | - | "Shaquile O'Neal" | 47 | - | "Steve Nash" | 45 | - | "Tim Duncan" | 42 | - | "Vince Carter" | 42 | + | VertexID | Age | + | "Grant Hill" | 46 | + | "Jason Kidd" | 45 | + | "Manu Ginobili" | 41 | + | "Ray Allen" | 43 | + | "Shaquille O'Neal" | 47 | + | "Steve Nash" | 45 | + | "Tim Duncan" | 42 | + | "Vince Carter" | 42 | When executing query: """ LOOKUP ON player WHERE player.age < 40 diff --git a/tests/tck/features/lookup/ByIndex.intVid.feature b/tests/tck/features/lookup/ByIndex.intVid.feature index 1e56aa4b289..7f6c3466b63 100644 --- a/tests/tck/features/lookup/ByIndex.intVid.feature +++ b/tests/tck/features/lookup/ByIndex.intVid.feature @@ -244,12 +244,12 @@ Feature: Lookup by index itself in integer vid | 'Grant Hill' | 'Magic' | 0 | | 'Grant Hill' | 'Suns' | 0 | | 'Grant Hill' | 'Clippers' | 0 | - | "Shaquile O'Neal" | 'Magic' | 0 | - | "Shaquile O'Neal" | 'Lakers' | 0 | - | "Shaquile O'Neal" | 'Heat' | 0 | - | "Shaquile O'Neal" | 'Suns' | 0 | - | "Shaquile O'Neal" | 'Cavaliers' | 0 | - | "Shaquile O'Neal" | 'Celtics' | 0 | + | "Shaquille O'Neal" | 'Magic' | 0 | + | "Shaquille O'Neal" | 'Lakers' | 0 | + | "Shaquille O'Neal" | 'Heat' | 0 | + | "Shaquille O'Neal" | 'Suns' | 0 | + | "Shaquille O'Neal" | 'Cavaliers' | 0 | + | "Shaquille O'Neal" | 'Celtics' | 0 | | 'JaVale McGee' | 'Wizards' | 0 | | 'JaVale McGee' | 'Nuggets' | 0 | | 'JaVale McGee' | 'Mavericks' | 0 | @@ -402,12 +402,12 @@ Feature: Lookup by index itself in integer vid | 'Grant Hill' | 'Magic' | 0 | 2000 | | 'Grant Hill' | 'Suns' | 0 | 2007 | | 'Grant Hill' | 'Clippers' | 0 | 2012 | - | "Shaquile O'Neal" | 'Magic' | 0 | 1992 | - | "Shaquile O'Neal" | 'Lakers' | 0 | 1996 | - | "Shaquile O'Neal" | 'Heat' | 0 | 2004 | - | "Shaquile O'Neal" | 'Suns' | 0 | 2008 | - | "Shaquile O'Neal" | 'Cavaliers' | 0 | 2009 | - | "Shaquile O'Neal" | 'Celtics' | 0 | 2010 | + | "Shaquille O'Neal" | 'Magic' | 0 | 1992 | + | "Shaquille O'Neal" | 'Lakers' | 0 | 1996 | + | "Shaquille O'Neal" | 'Heat' | 0 | 2004 | + | "Shaquille O'Neal" | 'Suns' | 0 | 2008 | + | "Shaquille O'Neal" | 'Cavaliers' | 0 | 2009 | + | "Shaquille O'Neal" | 'Celtics' | 0 | 2010 | | 'JaVale McGee' | 'Wizards' | 0 | 2008 | | 'JaVale McGee' | 'Nuggets' | 0 | 2012 | | 'JaVale McGee' | 'Mavericks' | 0 | 2015 | @@ -458,59 +458,59 @@ Feature: Lookup by index itself in integer vid LOOKUP ON player WHERE player.age > 40 YIELD player.age AS Age """ Then the result should be, in any order, and the columns 0 should be hashed: - | VertexID | Age | - | "Grant Hill" | 46 | - | "Jason Kidd" | 45 | - | "Manu Ginobili" | 41 | - | "Ray Allen" | 43 | - | "Shaquile O'Neal" | 47 | - | "Steve Nash" | 45 | - | "Tim Duncan" | 42 | - | "Vince Carter" | 42 | + | VertexID | Age | + | "Grant Hill" | 46 | + | "Jason Kidd" | 45 | + | "Manu Ginobili" | 41 | + | "Ray Allen" | 43 | + | "Shaquille O'Neal" | 47 | + | "Steve Nash" | 45 | + | "Tim Duncan" | 42 | + | "Vince Carter" | 42 | When executing query: """ LOOKUP ON player WHERE player.age >= 40.0 YIELD player.age AS Age """ Then the result should be, in any order, and the columns 0 should be hashed: - | VertexID | Age | - | "Grant Hill" | 46 | - | "Jason Kidd" | 45 | - | "Manu Ginobili" | 41 | - | "Ray Allen" | 43 | - | "Shaquile O'Neal" | 47 | - | "Steve Nash" | 45 | - | "Tim Duncan" | 42 | - | "Vince Carter" | 42 | - | "Dirk Nowitzki" | 40 | - | "Kobe Bryant" | 40 | + | VertexID | Age | + | "Grant Hill" | 46 | + | "Jason Kidd" | 45 | + | "Manu Ginobili" | 41 | + | "Ray Allen" | 43 | + | "Shaquille O'Neal" | 47 | + | "Steve Nash" | 45 | + | "Tim Duncan" | 42 | + | "Vince Carter" | 42 | + | "Dirk Nowitzki" | 40 | + | "Kobe Bryant" | 40 | When executing query: """ LOOKUP ON player WHERE player.age > 40.5 YIELD player.age AS Age """ Then the result should be, in any order, and the columns 0 should be hashed: - | VertexID | Age | - | "Grant Hill" | 46 | - | "Jason Kidd" | 45 | - | "Manu Ginobili" | 41 | - | "Ray Allen" | 43 | - | "Shaquile O'Neal" | 47 | - | "Steve Nash" | 45 | - | "Tim Duncan" | 42 | - | "Vince Carter" | 42 | + | VertexID | Age | + | "Grant Hill" | 46 | + | "Jason Kidd" | 45 | + | "Manu Ginobili" | 41 | + | "Ray Allen" | 43 | + | "Shaquille O'Neal" | 47 | + | "Steve Nash" | 45 | + | "Tim Duncan" | 42 | + | "Vince Carter" | 42 | When executing query: """ LOOKUP ON player WHERE player.age >= 40.5 YIELD player.age AS Age """ Then the result should be, in any order, and the columns 0 should be hashed: - | VertexID | Age | - | "Grant Hill" | 46 | - | "Jason Kidd" | 45 | - | "Manu Ginobili" | 41 | - | "Ray Allen" | 43 | - | "Shaquile O'Neal" | 47 | - | "Steve Nash" | 45 | - | "Tim Duncan" | 42 | - | "Vince Carter" | 42 | + | VertexID | Age | + | "Grant Hill" | 46 | + | "Jason Kidd" | 45 | + | "Manu Ginobili" | 41 | + | "Ray Allen" | 43 | + | "Shaquille O'Neal" | 47 | + | "Steve Nash" | 45 | + | "Tim Duncan" | 42 | + | "Vince Carter" | 42 | When executing query: """ LOOKUP ON player WHERE player.age < 40 diff --git a/tests/tck/features/lookup/Output.feature b/tests/tck/features/lookup/Output.feature index f0ffe610a0b..27e64f0a7c0 100644 --- a/tests/tck/features/lookup/Output.feature +++ b/tests/tck/features/lookup/Output.feature @@ -14,7 +14,7 @@ Feature: Lookup with output | 'Kobe Bryant' | | 'Dirk Nowitzki' | - Scenario: [1] tag ouput with yield rename + Scenario: [1] tag output with yield rename When executing query: """ LOOKUP ON player WHERE player.age == 40 YIELD player.name AS name | @@ -36,7 +36,7 @@ Feature: Lookup with output | 'Kobe Bryant' | | 'Dirk Nowitzki' | - Scenario: [1] tag ouput with yield rename by var + Scenario: [1] tag output with yield rename by var When executing query: """ $a = LOOKUP ON player WHERE player.age == 40 YIELD player.name AS name; diff --git a/tests/tck/features/lookup/Output.intVid.feature b/tests/tck/features/lookup/Output.intVid.feature index b22430945ef..d177623e6df 100644 --- a/tests/tck/features/lookup/Output.intVid.feature +++ b/tests/tck/features/lookup/Output.intVid.feature @@ -14,7 +14,7 @@ Feature: Lookup with output in integer vid | 'Kobe Bryant' | | 'Dirk Nowitzki' | - Scenario: [1] tag ouput with yield rename + Scenario: [1] tag output with yield rename When executing query: """ LOOKUP ON player WHERE player.age == 40 YIELD player.name AS name | @@ -36,7 +36,7 @@ Feature: Lookup with output in integer vid | 'Kobe Bryant' | | 'Dirk Nowitzki' | - Scenario: [1] tag ouput with yield rename by var + Scenario: [1] tag output with yield rename by var When executing query: """ $a = LOOKUP ON player WHERE player.age == 40 YIELD player.name AS name; diff --git a/tests/tck/features/lookup/TagIndexFullScan.feature b/tests/tck/features/lookup/TagIndexFullScan.feature index 85e189d9b0c..09169ed8d8b 100644 --- a/tests/tck/features/lookup/TagIndexFullScan.feature +++ b/tests/tck/features/lookup/TagIndexFullScan.feature @@ -336,7 +336,7 @@ Feature: Lookup tag index full scan | "Ricky Rubio" | 28 | | "Rudy Gay" | 32 | | "Russell Westbrook" | 30 | - | "Shaquile O'Neal" | 47 | + | "Shaquille O'Neal" | 47 | | "Stephen Curry" | 31 | | "Steve Nash" | 45 | | "Tiago Splitter" | 34 | diff --git a/tests/tck/features/match/Base.IntVid.feature b/tests/tck/features/match/Base.IntVid.feature index 20d15d7eae4..0b95df4156d 100644 --- a/tests/tck/features/match/Base.IntVid.feature +++ b/tests/tck/features/match/Base.IntVid.feature @@ -190,7 +190,7 @@ Feature: Basic match | "Tony Parker" | "Spurs" | "David West" | | "Tony Parker" | "Spurs" | "Dejounte Murray" | - Scenario: Uistinct + Scenario: Distinct When executing query: """ MATCH (:player{name:'Dwyane Wade'}) -[:like]-> () -[:like]-> (v3) diff --git a/tests/tck/features/match/Base.feature b/tests/tck/features/match/Base.feature index 205831567ca..26227d58e9b 100644 --- a/tests/tck/features/match/Base.feature +++ b/tests/tck/features/match/Base.feature @@ -204,12 +204,12 @@ Feature: Basic match MATCH (v:player)-[e:like]-(v2) where v.age == 38 RETURN * """ Then the result should be, in any order, with relax comparison: - | v | e | v2 | - | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | [:like "Marc Gasol"->"Paul Gasol" @0 {likeness: 99}] | ("Marc Gasol" :player{age: 34, name: "Marc Gasol"}) | - | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | [:like "Paul Gasol"->"Kobe Bryant" @0 {likeness: 90}] | ("Kobe Bryant" :player{age: 40, name: "Kobe Bryant"}) | - | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | [:like "Paul Gasol"->"Marc Gasol" @0 {likeness: 99}] | ("Marc Gasol" :player{age: 34, name: "Marc Gasol"}) | - | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | [:like "Yao Ming"->"Shaquile O'Neal" @0 {likeness: 90}] | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | - | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | [:like "Yao Ming"->"Tracy McGrady" @0 {likeness: 90}] | ("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"}) | + | v | e | v2 | + | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | [:like "Marc Gasol"->"Paul Gasol" @0 {likeness: 99}] | ("Marc Gasol" :player{age: 34, name: "Marc Gasol"}) | + | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | [:like "Paul Gasol"->"Kobe Bryant" @0 {likeness: 90}] | ("Kobe Bryant" :player{age: 40, name: "Kobe Bryant"}) | + | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | [:like "Paul Gasol"->"Marc Gasol" @0 {likeness: 99}] | ("Marc Gasol" :player{age: 34, name: "Marc Gasol"}) | + | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | [:like "Yao Ming"->"Shaquille O'Neal" @0 {likeness: 90}] | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | + | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | [:like "Yao Ming"->"Tracy McGrady" @0 {likeness: 90}] | ("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"}) | When executing query: """ MATCH (v:player)-[e:like]->(v2) where id(v) == "Tim Duncan" RETURN DISTINCT properties(e) as props, e @@ -254,7 +254,7 @@ Feature: Basic match | "Tony Parker" | "Spurs" | "David West" | | "Tony Parker" | "Spurs" | "Dejounte Murray" | - Scenario: Uistinct + Scenario: Distinct When executing query: """ MATCH (:player{name:'Dwyane Wade'}) -[:like]-> () -[:like]-> (v3) diff --git a/tests/tck/features/match/MatchById.IntVid.feature b/tests/tck/features/match/MatchById.IntVid.feature index 56a0a5b6b7f..6db58ed487b 100644 --- a/tests/tck/features/match/MatchById.IntVid.feature +++ b/tests/tck/features/match/MatchById.IntVid.feature @@ -601,7 +601,7 @@ Feature: Integer Vid Match By Id | [[:like "Dejounte Murray"->"Tim Duncan"@0],[:like "Dejounte Murray"->"Marco Belinelli"@0],[:like "Marco Belinelli"->"Tony Parker"@0]] | ("Tony Parker") | | [[:like "Danny Green"->"Tim Duncan"@0],[:like "Marco Belinelli"->"Danny Green"@0],[:like "Marco Belinelli"->"Tony Parker"@0]] | ("Tony Parker") | | [[:like "Danny Green"->"Tim Duncan"@0],[:like "Danny Green"->"Marco Belinelli"@0],[:like "Marco Belinelli"->"Tony Parker"@0]] | ("Tony Parker") | - | [[:like "Shaquile O'Neal"->"Tim Duncan"@0],[:like "Yao Ming"->"Shaquile O'Neal"@0],[:like "Yao Ming"->"Tracy McGrady"@0]] | ("Tracy McGrady") | + | [[:like "Shaquille O'Neal"->"Tim Duncan"@0],[:like "Yao Ming"->"Shaquille O'Neal"@0],[:like "Yao Ming"->"Tracy McGrady"@0]] | ("Tracy McGrady") | | [[:like "LaMarcus Aldridge"->"Tim Duncan"@0],[:like "Tony Parker"->"LaMarcus Aldridge"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | | [[:like "LaMarcus Aldridge"->"Tim Duncan"@0],[:like "LaMarcus Aldridge"->"Tony Parker"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | | [[:like "Dejounte Murray"->"Tim Duncan"@0],[:like "Dejounte Murray"->"Tony Parker"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | @@ -774,10 +774,10 @@ Feature: Integer Vid Match By Id | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Marco Belinelli"->"Tim Duncan"@0]] | ("Marco Belinelli") | | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Tim Duncan"->"Tony Parker"@0],[:like "Marco Belinelli"->"Tim Duncan"@0]] | ("Marco Belinelli") | | [[:like "Tim Duncan"->"Tony Parker"@0],[:like "Tony Parker"->"Tim Duncan"@0],[:like "Marco Belinelli"->"Tim Duncan"@0]] | ("Marco Belinelli") | - | [[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Shaquile O'Neal"->"Tim Duncan"@0]] | ("Shaquile O'Neal") | - | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Shaquile O'Neal"->"Tim Duncan"@0]] | ("Shaquile O'Neal") | - | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Tim Duncan"->"Tony Parker"@0],[:like "Shaquile O'Neal"->"Tim Duncan"@0]] | ("Shaquile O'Neal") | - | [[:like "Tim Duncan"->"Tony Parker"@0],[:like "Tony Parker"->"Tim Duncan"@0],[:like "Shaquile O'Neal"->"Tim Duncan"@0]] | ("Shaquile O'Neal") | + | [[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Shaquille O'Neal"->"Tim Duncan"@0]] | ("Shaquille O'Neal") | + | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Shaquille O'Neal"->"Tim Duncan"@0]] | ("Shaquille O'Neal") | + | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Tim Duncan"->"Tony Parker"@0],[:like "Shaquille O'Neal"->"Tim Duncan"@0]] | ("Shaquille O'Neal") | + | [[:like "Tim Duncan"->"Tony Parker"@0],[:like "Tony Parker"->"Tim Duncan"@0],[:like "Shaquille O'Neal"->"Tim Duncan"@0]] | ("Shaquille O'Neal") | | [[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Tiago Splitter"->"Tim Duncan"@0]] | ("Tiago Splitter") | | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Tiago Splitter"->"Tim Duncan"@0]] | ("Tiago Splitter") | | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Tim Duncan"->"Tony Parker"@0],[:like "Tiago Splitter"->"Tim Duncan"@0]] | ("Tiago Splitter") | @@ -822,8 +822,8 @@ Feature: Integer Vid Match By Id | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Tony Parker"->"Manu Ginobili"@0]] | ("Tony Parker") | | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0]] | ("Tim Duncan") | | [[:like "Tiago Splitter"->"Tim Duncan"@0],[:like "Tiago Splitter"->"Manu Ginobili"@0]] | ("Manu Ginobili") | - | [[:like "Shaquile O'Neal"->"Tim Duncan"@0],[:like "Yao Ming"->"Shaquile O'Neal"@0]] | ("Yao Ming") | - | [[:like "Shaquile O'Neal"->"Tim Duncan"@0],[:like "Shaquile O'Neal"->"JaVale McGee"@0]] | ("JaVale McGee") | + | [[:like "Shaquille O'Neal"->"Tim Duncan"@0],[:like "Yao Ming"->"Shaquille O'Neal"@0]] | ("Yao Ming") | + | [[:like "Shaquille O'Neal"->"Tim Duncan"@0],[:like "Shaquille O'Neal"->"JaVale McGee"@0]] | ("JaVale McGee") | | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | | [[:like "Tim Duncan"->"Tony Parker"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Dejounte Murray"->"Tony Parker"@0]] | ("Dejounte Murray") | diff --git a/tests/tck/features/match/MatchById.feature b/tests/tck/features/match/MatchById.feature index bded9c83ad8..d54e15c247c 100644 --- a/tests/tck/features/match/MatchById.feature +++ b/tests/tck/features/match/MatchById.feature @@ -601,7 +601,7 @@ Feature: Match By Id | [[:like "Dejounte Murray"->"Tim Duncan"@0],[:like "Dejounte Murray"->"Marco Belinelli"@0],[:like "Marco Belinelli"->"Tony Parker"@0]] | ("Tony Parker") | | [[:like "Danny Green"->"Tim Duncan"@0],[:like "Marco Belinelli"->"Danny Green"@0],[:like "Marco Belinelli"->"Tony Parker"@0]] | ("Tony Parker") | | [[:like "Danny Green"->"Tim Duncan"@0],[:like "Danny Green"->"Marco Belinelli"@0],[:like "Marco Belinelli"->"Tony Parker"@0]] | ("Tony Parker") | - | [[:like "Shaquile O'Neal"->"Tim Duncan"@0],[:like "Yao Ming"->"Shaquile O'Neal"@0],[:like "Yao Ming"->"Tracy McGrady"@0]] | ("Tracy McGrady") | + | [[:like "Shaquille O'Neal"->"Tim Duncan"@0],[:like "Yao Ming"->"Shaquille O'Neal"@0],[:like "Yao Ming"->"Tracy McGrady"@0]] | ("Tracy McGrady") | | [[:like "LaMarcus Aldridge"->"Tim Duncan"@0],[:like "Tony Parker"->"LaMarcus Aldridge"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | | [[:like "LaMarcus Aldridge"->"Tim Duncan"@0],[:like "LaMarcus Aldridge"->"Tony Parker"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | | [[:like "Dejounte Murray"->"Tim Duncan"@0],[:like "Dejounte Murray"->"Tony Parker"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | @@ -774,10 +774,10 @@ Feature: Match By Id | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Marco Belinelli"->"Tim Duncan"@0]] | ("Marco Belinelli") | | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Tim Duncan"->"Tony Parker"@0],[:like "Marco Belinelli"->"Tim Duncan"@0]] | ("Marco Belinelli") | | [[:like "Tim Duncan"->"Tony Parker"@0],[:like "Tony Parker"->"Tim Duncan"@0],[:like "Marco Belinelli"->"Tim Duncan"@0]] | ("Marco Belinelli") | - | [[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Shaquile O'Neal"->"Tim Duncan"@0]] | ("Shaquile O'Neal") | - | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Shaquile O'Neal"->"Tim Duncan"@0]] | ("Shaquile O'Neal") | - | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Tim Duncan"->"Tony Parker"@0],[:like "Shaquile O'Neal"->"Tim Duncan"@0]] | ("Shaquile O'Neal") | - | [[:like "Tim Duncan"->"Tony Parker"@0],[:like "Tony Parker"->"Tim Duncan"@0],[:like "Shaquile O'Neal"->"Tim Duncan"@0]] | ("Shaquile O'Neal") | + | [[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Shaquille O'Neal"->"Tim Duncan"@0]] | ("Shaquille O'Neal") | + | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Shaquille O'Neal"->"Tim Duncan"@0]] | ("Shaquille O'Neal") | + | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Tim Duncan"->"Tony Parker"@0],[:like "Shaquille O'Neal"->"Tim Duncan"@0]] | ("Shaquille O'Neal") | + | [[:like "Tim Duncan"->"Tony Parker"@0],[:like "Tony Parker"->"Tim Duncan"@0],[:like "Shaquille O'Neal"->"Tim Duncan"@0]] | ("Shaquille O'Neal") | | [[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Tiago Splitter"->"Tim Duncan"@0]] | ("Tiago Splitter") | | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0],[:like "Tiago Splitter"->"Tim Duncan"@0]] | ("Tiago Splitter") | | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Tim Duncan"->"Tony Parker"@0],[:like "Tiago Splitter"->"Tim Duncan"@0]] | ("Tiago Splitter") | @@ -822,8 +822,8 @@ Feature: Match By Id | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Tony Parker"->"Manu Ginobili"@0]] | ("Tony Parker") | | [[:like "Tim Duncan"->"Manu Ginobili"@0],[:like "Manu Ginobili"->"Tim Duncan"@0]] | ("Tim Duncan") | | [[:like "Tiago Splitter"->"Tim Duncan"@0],[:like "Tiago Splitter"->"Manu Ginobili"@0]] | ("Manu Ginobili") | - | [[:like "Shaquile O'Neal"->"Tim Duncan"@0],[:like "Yao Ming"->"Shaquile O'Neal"@0]] | ("Yao Ming") | - | [[:like "Shaquile O'Neal"->"Tim Duncan"@0],[:like "Shaquile O'Neal"->"JaVale McGee"@0]] | ("JaVale McGee") | + | [[:like "Shaquille O'Neal"->"Tim Duncan"@0],[:like "Yao Ming"->"Shaquille O'Neal"@0]] | ("Yao Ming") | + | [[:like "Shaquille O'Neal"->"Tim Duncan"@0],[:like "Shaquille O'Neal"->"JaVale McGee"@0]] | ("JaVale McGee") | | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | | [[:like "Tim Duncan"->"Tony Parker"@0],[:like "Boris Diaw"->"Tony Parker"@0]] | ("Boris Diaw") | | [[:like "Tony Parker"->"Tim Duncan"@0],[:like "Dejounte Murray"->"Tony Parker"@0]] | ("Dejounte Murray") | diff --git a/tests/tck/features/match/MatchGroupBy.feature b/tests/tck/features/match/MatchGroupBy.feature index 7eca9555b48..720b4c7c8fe 100644 --- a/tests/tck/features/match/MatchGroupBy.feature +++ b/tests/tck/features/match/MatchGroupBy.feature @@ -97,13 +97,13 @@ Feature: Match GroupBy SKIP 10 LIMIT 6; """ Then the result should be, in order, with relax comparison: - | id | count | sum | max | min | age | lb | - | "Ray Allen" | 1 | 43.0 | 43 | 43 | 44.0 | ["player"] | - | "Shaquile O'Neal" | 1 | 47.0 | 47 | 47 | 48.0 | ["player"] | - | "Steve Nash" | 1 | 45.0 | 45 | 45 | 46.0 | ["player"] | - | "Tim Duncan" | 1 | 42.0 | 42 | 42 | 43.0 | ["bachelor", "player"] | - | "Tony Parker" | 1 | 36.0 | 36 | 36 | 37.0 | ["player"] | - | "Tracy McGrady" | 1 | 39.0 | 39 | 39 | 40.0 | ["player"] | + | id | count | sum | max | min | age | lb | + | "Ray Allen" | 1 | 43.0 | 43 | 43 | 44.0 | ["player"] | + | "Shaquille O'Neal" | 1 | 47.0 | 47 | 47 | 48.0 | ["player"] | + | "Steve Nash" | 1 | 45.0 | 45 | 45 | 46.0 | ["player"] | + | "Tim Duncan" | 1 | 42.0 | 42 | 42 | 43.0 | ["bachelor", "player"] | + | "Tony Parker" | 1 | 36.0 | 36 | 36 | 37.0 | ["player"] | + | "Tracy McGrady" | 1 | 39.0 | 39 | 39 | 40.0 | ["player"] | Scenario: [5] Match GroupBy When executing query: @@ -121,16 +121,16 @@ Feature: Match GroupBy SKIP 10 LIMIT 20; """ Then the result should be, in order, with relax comparison: - | id | count | sum | max | min | age | lb | - | "Shaquile O'Neal" | 1 | 47.0 | 31 | 47 | 48.0 | ["player"] | - | "Shaquile O'Neal" | 1 | 47.0 | 42 | 47 | 48.0 | ["bachelor", "player"] | - | "Steve Nash" | 4 | 180.0 | 45 | 45 | 46.0 | ["player"] | - | "Tim Duncan" | 2 | 84.0 | 41 | 42 | 43.0 | ["player"] | - | "Tony Parker" | 1 | 36.0 | 42 | 36 | 37.0 | ["bachelor", "player"] | - | "Tony Parker" | 2 | 72.0 | 41 | 36 | 37.0 | ["player"] | - | "Tracy McGrady" | 3 | 117.0 | 46 | 39 | 40.0 | ["player"] | - | "Vince Carter" | 2 | 84.0 | 45 | 42 | 43.0 | ["player"] | - | "Yao Ming" | 2 | 76.0 | 47 | 38 | 39.0 | ["player"] | + | id | count | sum | max | min | age | lb | + | "Shaquille O'Neal" | 1 | 47.0 | 31 | 47 | 48.0 | ["player"] | + | "Shaquille O'Neal" | 1 | 47.0 | 42 | 47 | 48.0 | ["bachelor", "player"] | + | "Steve Nash" | 4 | 180.0 | 45 | 45 | 46.0 | ["player"] | + | "Tim Duncan" | 2 | 84.0 | 41 | 42 | 43.0 | ["player"] | + | "Tony Parker" | 1 | 36.0 | 42 | 36 | 37.0 | ["bachelor", "player"] | + | "Tony Parker" | 2 | 72.0 | 41 | 36 | 37.0 | ["player"] | + | "Tracy McGrady" | 3 | 117.0 | 46 | 39 | 40.0 | ["player"] | + | "Vince Carter" | 2 | 84.0 | 45 | 42 | 43.0 | ["player"] | + | "Yao Ming" | 2 | 76.0 | 47 | 38 | 39.0 | ["player"] | Scenario: [6] Match GroupBy When executing query: diff --git a/tests/tck/features/match/PipeAndVariable.feature b/tests/tck/features/match/PipeAndVariable.feature index 071ce5f09c5..d175f0da03f 100644 --- a/tests/tck/features/match/PipeAndVariable.feature +++ b/tests/tck/features/match/PipeAndVariable.feature @@ -29,7 +29,7 @@ Feature: Pipe or use variable to store the match results | 42 | false | "Tim Duncan" | "LaMarcus Aldridge" | | 42 | false | "Tim Duncan" | "Manu Ginobili" | | 42 | false | "Tim Duncan" | "Marco Belinelli" | - | 42 | false | "Tim Duncan" | "Shaquile O'Neal" | + | 42 | false | "Tim Duncan" | "Shaquille O'Neal" | | 42 | false | "Tim Duncan" | "Tiago Splitter" | | 42 | true | "Tim Duncan" | "Tony Parker" | @@ -56,7 +56,7 @@ Feature: Pipe or use variable to store the match results | 42 | false | "Tim Duncan" | "LaMarcus Aldridge" | | 42 | false | "Tim Duncan" | "Manu Ginobili" | | 42 | false | "Tim Duncan" | "Marco Belinelli" | - | 42 | false | "Tim Duncan" | "Shaquile O'Neal" | + | 42 | false | "Tim Duncan" | "Shaquille O'Neal" | | 42 | false | "Tim Duncan" | "Tiago Splitter" | | 42 | true | "Tim Duncan" | "Tony Parker" | diff --git a/tests/tck/features/match/SeekByEdge.feature b/tests/tck/features/match/SeekByEdge.feature index e949f54899e..ef1629c7652 100644 --- a/tests/tck/features/match/SeekByEdge.feature +++ b/tests/tck/features/match/SeekByEdge.feature @@ -150,12 +150,12 @@ Feature: Match seek by edge | "Grant Hill" | "Magic" | | "Grant Hill" | "Suns" | | "Grant Hill" | "Clippers" | - | "Shaquile O'Neal" | "Magic" | - | "Shaquile O'Neal" | "Lakers" | - | "Shaquile O'Neal" | "Heat" | - | "Shaquile O'Neal" | "Suns" | - | "Shaquile O'Neal" | "Cavaliers" | - | "Shaquile O'Neal" | "Celtics" | + | "Shaquille O'Neal" | "Magic" | + | "Shaquille O'Neal" | "Lakers" | + | "Shaquille O'Neal" | "Heat" | + | "Shaquille O'Neal" | "Suns" | + | "Shaquille O'Neal" | "Cavaliers" | + | "Shaquille O'Neal" | "Celtics" | | "JaVale McGee" | "Wizards" | | "JaVale McGee" | "Nuggets" | | "JaVale McGee" | "Mavericks" | @@ -309,12 +309,12 @@ Feature: Match seek by edge | "Grant Hill" | "Magic" | | "Grant Hill" | "Suns" | | "Grant Hill" | "Clippers" | - | "Shaquile O'Neal" | "Magic" | - | "Shaquile O'Neal" | "Lakers" | - | "Shaquile O'Neal" | "Heat" | - | "Shaquile O'Neal" | "Suns" | - | "Shaquile O'Neal" | "Cavaliers" | - | "Shaquile O'Neal" | "Celtics" | + | "Shaquille O'Neal" | "Magic" | + | "Shaquille O'Neal" | "Lakers" | + | "Shaquille O'Neal" | "Heat" | + | "Shaquille O'Neal" | "Suns" | + | "Shaquille O'Neal" | "Cavaliers" | + | "Shaquille O'Neal" | "Celtics" | | "JaVale McGee" | "Wizards" | | "JaVale McGee" | "Nuggets" | | "JaVale McGee" | "Mavericks" | @@ -468,12 +468,12 @@ Feature: Match seek by edge | "Magic" | "Grant Hill" | | "Clippers" | "Grant Hill" | | "Pistons" | "Grant Hill" | - | "Celtics" | "Shaquile O'Neal" | - | "Cavaliers" | "Shaquile O'Neal" | - | "Lakers" | "Shaquile O'Neal" | - | "Magic" | "Shaquile O'Neal" | - | "Suns" | "Shaquile O'Neal" | - | "Heat" | "Shaquile O'Neal" | + | "Celtics" | "Shaquille O'Neal" | + | "Cavaliers" | "Shaquille O'Neal" | + | "Lakers" | "Shaquille O'Neal" | + | "Magic" | "Shaquille O'Neal" | + | "Suns" | "Shaquille O'Neal" | + | "Heat" | "Shaquille O'Neal" | | "Warriors" | "JaVale McGee" | | "Mavericks" | "JaVale McGee" | | "Wizards" | "JaVale McGee" | @@ -519,7 +519,7 @@ Feature: Match seek by edge | "LeBron James" | "Lakers" | | "JaVale McGee" | "Lakers" | | "Dwight Howard" | "Lakers" | - | "Shaquile O'Neal" | "Lakers" | + | "Shaquille O'Neal" | "Lakers" | | "Paul Gasol" | "Lakers" | | "Ricky Rubio" | "Jazz" | | "Boris Diaw" | "Jazz" | @@ -547,7 +547,7 @@ Feature: Match seek by edge | "Dwight Howard" | "Magic" | | "Tracy McGrady" | "Magic" | | "Vince Carter" | "Magic" | - | "Shaquile O'Neal" | "Magic" | + | "Shaquille O'Neal" | "Magic" | | "Carmelo Anthony" | "Rockets" | | "Tracy McGrady" | "Rockets" | | "Dwight Howard" | "Rockets" | @@ -585,7 +585,7 @@ Feature: Match seek by edge | "Ray Allen" | "Heat" | | "Amar'e Stoudemire" | "Heat" | | "Dwyane Wade" | "Heat" | - | "Shaquile O'Neal" | "Heat" | + | "Shaquille O'Neal" | "Heat" | | "Marc Gasol" | "Grizzlies" | | "Kyle Anderson" | "Grizzlies" | | "Vince Carter" | "Grizzlies" | @@ -601,7 +601,7 @@ Feature: Match seek by edge | "Grant Hill" | "Suns" | | "Vince Carter" | "Suns" | | "Amar'e Stoudemire" | "Suns" | - | "Shaquile O'Neal" | "Suns" | + | "Shaquille O'Neal" | "Suns" | | "Jason Kidd" | "Suns" | | "Boris Diaw" | "Suns" | | "David West" | "Hornets" | @@ -616,13 +616,13 @@ Feature: Match seek by edge | "Dwyane Wade" | "Cavaliers" | | "Kyrie Irving" | "Cavaliers" | | "Danny Green" | "Cavaliers" | - | "Shaquile O'Neal" | "Cavaliers" | + | "Shaquille O'Neal" | "Cavaliers" | | "Marco Belinelli" | "Kings" | | "Rajon Rondo" | "Kings" | | "Rudy Gay" | "Kings" | | "Vince Carter" | "Kings" | | "Aron Baynes" | "Celtics" | - | "Shaquile O'Neal" | "Celtics" | + | "Shaquille O'Neal" | "Celtics" | | "Kyrie Irving" | "Celtics" | | "Rajon Rondo" | "Celtics" | | "Ray Allen" | "Celtics" | @@ -786,12 +786,12 @@ Feature: Match seek by edge | "Yao Ming" | "Tracy McGrady" | "Magic" | | "Yao Ming" | "Tracy McGrady" | "Rockets" | | "Yao Ming" | "Tracy McGrady" | "Raptors" | - | "Yao Ming" | "Shaquile O'Neal" | "Suns" | - | "Yao Ming" | "Shaquile O'Neal" | "Celtics" | - | "Yao Ming" | "Shaquile O'Neal" | "Heat" | - | "Yao Ming" | "Shaquile O'Neal" | "Magic" | - | "Yao Ming" | "Shaquile O'Neal" | "Cavaliers" | - | "Yao Ming" | "Shaquile O'Neal" | "Lakers" | + | "Yao Ming" | "Shaquille O'Neal" | "Suns" | + | "Yao Ming" | "Shaquille O'Neal" | "Celtics" | + | "Yao Ming" | "Shaquille O'Neal" | "Heat" | + | "Yao Ming" | "Shaquille O'Neal" | "Magic" | + | "Yao Ming" | "Shaquille O'Neal" | "Cavaliers" | + | "Yao Ming" | "Shaquille O'Neal" | "Lakers" | | "Dejounte Murray" | "Chris Paul" | "Hornets" | | "Dejounte Murray" | "Chris Paul" | "Clippers" | | "Dejounte Murray" | "Chris Paul" | "Rockets" | @@ -867,12 +867,12 @@ Feature: Match seek by edge | "Grant Hill" | "Tracy McGrady" | "Magic" | | "Grant Hill" | "Tracy McGrady" | "Rockets" | | "Grant Hill" | "Tracy McGrady" | "Raptors" | - | "Shaquile O'Neal" | "Tim Duncan" | "Spurs" | - | "Shaquile O'Neal" | "JaVale McGee" | "Lakers" | - | "Shaquile O'Neal" | "JaVale McGee" | "Warriors" | - | "Shaquile O'Neal" | "JaVale McGee" | "Wizards" | - | "Shaquile O'Neal" | "JaVale McGee" | "Nuggets" | - | "Shaquile O'Neal" | "JaVale McGee" | "Mavericks" | + | "Shaquille O'Neal" | "Tim Duncan" | "Spurs" | + | "Shaquille O'Neal" | "JaVale McGee" | "Lakers" | + | "Shaquille O'Neal" | "JaVale McGee" | "Warriors" | + | "Shaquille O'Neal" | "JaVale McGee" | "Wizards" | + | "Shaquille O'Neal" | "JaVale McGee" | "Nuggets" | + | "Shaquille O'Neal" | "JaVale McGee" | "Mavericks" | Scenario Outline: Seek by edge with range When executing query: @@ -1037,8 +1037,8 @@ Feature: Match seek by edge | "Grant Hill" | "Kobe Bryant" | | "Grant Hill" | "Grant Hill" | | "Grant Hill" | "Rudy Gay" | - | "Shaquile O'Neal" | "Tony Parker" | - | "Shaquile O'Neal" | "Manu Ginobili" | + | "Shaquille O'Neal" | "Tony Parker" | + | "Shaquille O'Neal" | "Manu Ginobili" | When executing query: """ match (p1)-[:like*1..2]->(p2) return p1.name, p2.name @@ -1196,7 +1196,7 @@ Feature: Match seek by edge | "Damian Lillard" | "LaMarcus Aldridge" | | "Damian Lillard" | "Tony Parker" | | "Damian Lillard" | "Tim Duncan" | - | "Yao Ming" | "Shaquile O'Neal" | + | "Yao Ming" | "Shaquille O'Neal" | | "Yao Ming" | "JaVale McGee" | | "Yao Ming" | "Tim Duncan" | | "Yao Ming" | "Tracy McGrady" | @@ -1280,10 +1280,10 @@ Feature: Match seek by edge | "Grant Hill" | "Kobe Bryant" | | "Grant Hill" | "Grant Hill" | | "Grant Hill" | "Rudy Gay" | - | "Shaquile O'Neal" | "JaVale McGee" | - | "Shaquile O'Neal" | "Tim Duncan" | - | "Shaquile O'Neal" | "Tony Parker" | - | "Shaquile O'Neal" | "Manu Ginobili" | + | "Shaquille O'Neal" | "JaVale McGee" | + | "Shaquille O'Neal" | "Tim Duncan" | + | "Shaquille O'Neal" | "Tony Parker" | + | "Shaquille O'Neal" | "Manu Ginobili" | When executing query: """ match (p1)-[:serve*2]->(p2) return p1.name, p2.name @@ -1447,7 +1447,7 @@ Feature: Match seek by edge | "Dwyane Wade" | "Chris Paul" | | "Dwyane Wade" | "Dwyane Wade" | | "Dwyane Wade" | "LeBron James" | - | "Yao Ming" | "Shaquile O'Neal" | + | "Yao Ming" | "Shaquille O'Neal" | | "Yao Ming" | "Tracy McGrady" | | "Yao Ming" | "Kobe Bryant" | | "Yao Ming" | "Grant Hill" | diff --git a/tests/tck/features/match/VariableLengthPattern.feature b/tests/tck/features/match/VariableLengthPattern.feature index 74adff6f9bf..64f87063e60 100644 --- a/tests/tck/features/match/VariableLengthPattern.feature +++ b/tests/tck/features/match/VariableLengthPattern.feature @@ -257,7 +257,7 @@ Feature: Variable length Pattern match (m to n) | [[:like "Tim Duncan"->"Manu Ginobili"]] | | [[:like "Tim Duncan"->"Tony Parker"]] | | [[:like "Tim Duncan"<-"Dejounte Murray"]] | - | [[:like "Tim Duncan"<-"Shaquile O'Neal"]] | + | [[:like "Tim Duncan"<-"Shaquille O'Neal"]] | | [[:like "Tim Duncan"<-"Marco Belinelli"]] | | [[:like "Tim Duncan"<-"Boris Diaw"]] | | [[:like "Tim Duncan"<-"Manu Ginobili"]] | @@ -278,7 +278,7 @@ Feature: Variable length Pattern match (m to n) | [[:like "Tim Duncan"->"Manu Ginobili"]] | | [[:like "Tim Duncan"->"Tony Parker"]] | | [[:like "Tim Duncan"<-"Dejounte Murray"]] | - | [[:like "Tim Duncan"<-"Shaquile O'Neal"]] | + | [[:like "Tim Duncan"<-"Shaquille O'Neal"]] | | [[:like "Tim Duncan"<-"Marco Belinelli"]] | | [[:like "Tim Duncan"<-"Boris Diaw"]] | | [[:like "Tim Duncan"<-"Manu Ginobili"]] | diff --git a/tests/tck/features/match/VariableLengthPattern.intVid.feature b/tests/tck/features/match/VariableLengthPattern.intVid.feature index 1b2b6a67e7b..33719af1ed7 100644 --- a/tests/tck/features/match/VariableLengthPattern.intVid.feature +++ b/tests/tck/features/match/VariableLengthPattern.intVid.feature @@ -257,7 +257,7 @@ Feature: Integer Vid Variable length Pattern match (m to n) | [[:like "Tim Duncan"->"Manu Ginobili"]] | | [[:like "Tim Duncan"->"Tony Parker"]] | | [[:like "Tim Duncan"<-"Dejounte Murray"]] | - | [[:like "Tim Duncan"<-"Shaquile O'Neal"]] | + | [[:like "Tim Duncan"<-"Shaquille O'Neal"]] | | [[:like "Tim Duncan"<-"Marco Belinelli"]] | | [[:like "Tim Duncan"<-"Boris Diaw"]] | | [[:like "Tim Duncan"<-"Manu Ginobili"]] | @@ -278,7 +278,7 @@ Feature: Integer Vid Variable length Pattern match (m to n) | [[:like "Tim Duncan"->"Manu Ginobili"]] | | [[:like "Tim Duncan"->"Tony Parker"]] | | [[:like "Tim Duncan"<-"Dejounte Murray"]] | - | [[:like "Tim Duncan"<-"Shaquile O'Neal"]] | + | [[:like "Tim Duncan"<-"Shaquille O'Neal"]] | | [[:like "Tim Duncan"<-"Marco Belinelli"]] | | [[:like "Tim Duncan"<-"Boris Diaw"]] | | [[:like "Tim Duncan"<-"Manu Ginobili"]] | diff --git a/tests/tck/features/match/With.feature b/tests/tck/features/match/With.feature index f7a013e6af3..57a9de0c5b7 100644 --- a/tests/tck/features/match/With.feature +++ b/tests/tck/features/match/With.feature @@ -92,8 +92,8 @@ Feature: With clause RETURN collect(names) """ Then the result should be, in any order, with relax comparison: - | collect(names) | - | ["Tony Parker", "Tiago Splitter", "Spurs", "Shaquile O'Neal", "Marco Belinelli"] | + | collect(names) | + | ["Tony Parker", "Tiago Splitter", "Spurs", "Shaquille O'Neal", "Marco Belinelli"] | When profiling query: """ MATCH (v:player) @@ -105,7 +105,7 @@ Feature: With clause """ Then the result should be, in order, with relax comparison: | v | age | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | 47 | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | 47 | | ("Grant Hill" :player{age: 46, name: "Grant Hill"}) | 46 | | ("Jason Kidd" :player{age: 45, name: "Jason Kidd"}) | 45 | | ("Steve Nash" :player{age: 45, name: "Steve Nash"}) | 45 | @@ -126,18 +126,15 @@ Feature: With clause | ("Carmelo Anthony" :player{age: 34, name: "Carmelo Anthony"}) | 34 | | ("LeBron James" :player{age: 34, name: "LeBron James"}) | 34 | And the execution plan should be: - | id | name | dependencies | operator info | - | 13 | Project | 12 | | - | 12 | Filter | 17 | {"isStable": "true"} | - | 17 | TopN | 9 | | - | 9 | Project | 8 | | - | 8 | Filter | 7 | {"isStable": "false"} | - | 7 | Project | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 16 | {"isStable": "false"} | - | 16 | GetVertices | 1 | | - | 1 | IndexScan | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 8 | Project | 7 | | + | 7 | Filter | 11 | | + | 11 | TopN | 4 | | + | 4 | Project | 3 | | + | 3 | Project | 2 | | + | 2 | AppendVertices | 1 | | + | 1 | IndexScan | 0 | | + | 0 | Start | | | When executing query: """ MATCH (v:player)-[:like]->(v2) diff --git a/tests/tck/features/match/ZeroStep.feature b/tests/tck/features/match/ZeroStep.feature index 782c079d06b..cbd0ba0a6f0 100644 --- a/tests/tck/features/match/ZeroStep.feature +++ b/tests/tck/features/match/ZeroStep.feature @@ -41,7 +41,7 @@ Feature: Variable length Pattern match (0 step) | [[:like "LaMarcus Aldridge"->"Tim Duncan" @0 {likeness: 75}]] | | [[:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}]] | | [[:like "Marco Belinelli"->"Tim Duncan" @0 {likeness: 55}]] | - | [[:like "Shaquile O'Neal"->"Tim Duncan" @0 {likeness: 80}]] | + | [[:like "Shaquille O'Neal"->"Tim Duncan" @0 {likeness: 80}]] | | [[:like "Tiago Splitter"->"Tim Duncan" @0 {likeness: 80}]] | | [[:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}]] | | [[:like "Tim Duncan"->"Manu Ginobili" @0 {likeness: 95}]] | @@ -118,7 +118,7 @@ Feature: Variable length Pattern match (0 step) | [[:like "Tracy McGrady"->"Rudy Gay" @0 {likeness: 90}], [:like "Grant Hill"->"Tracy McGrady" @0 {likeness: 90}]] | ("Grant Hill" :player{age: 46, name: "Grant Hill"}) | | [[:like "Tracy McGrady"->"Rudy Gay" @0 {likeness: 90}], [:like "Vince Carter"->"Tracy McGrady" @0 {likeness: 90}]] | ("Vince Carter" :player{age: 42, name: "Vince Carter"}) | | [[:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}], [:like "Tiago Splitter"->"Manu Ginobili" @0 {likeness: 90}]] | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | - | [[:like "Yao Ming"->"Tracy McGrady" @0 {likeness: 90}], [:like "Yao Ming"->"Shaquile O'Neal" @0 {likeness: 90}]] | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | [[:like "Yao Ming"->"Tracy McGrady" @0 {likeness: 90}], [:like "Yao Ming"->"Shaquille O'Neal" @0 {likeness: 90}]] | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | [[:like "Tracy McGrady"->"Grant Hill" @0 {likeness: 90}], [:like "Grant Hill"->"Tracy McGrady" @0 {likeness: 90}]] | ("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"}) | | [[:like "Tracy McGrady"->"Rudy Gay" @0 {likeness: 90}], [:like "Yao Ming"->"Tracy McGrady" @0 {likeness: 90}]] | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | | [[:like "Tiago Splitter"->"Manu Ginobili" @0 {likeness: 90}], [:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}]] | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | @@ -271,14 +271,14 @@ Feature: Variable length Pattern match (0 step) | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | diff --git a/tests/tck/features/match/ZeroStep.intVid.feature b/tests/tck/features/match/ZeroStep.intVid.feature index bfedac3d8f3..457fda55f0e 100644 --- a/tests/tck/features/match/ZeroStep.intVid.feature +++ b/tests/tck/features/match/ZeroStep.intVid.feature @@ -41,7 +41,7 @@ Feature: Variable length Pattern match int vid (0 step) | [[:like "LaMarcus Aldridge"->"Tim Duncan" @0 {likeness: 75}]] | | [[:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}]] | | [[:like "Marco Belinelli"->"Tim Duncan" @0 {likeness: 55}]] | - | [[:like "Shaquile O'Neal"->"Tim Duncan" @0 {likeness: 80}]] | + | [[:like "Shaquille O'Neal"->"Tim Duncan" @0 {likeness: 80}]] | | [[:like "Tiago Splitter"->"Tim Duncan" @0 {likeness: 80}]] | | [[:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}]] | | [[:like "Tim Duncan"->"Manu Ginobili" @0 {likeness: 95}]] | @@ -118,7 +118,7 @@ Feature: Variable length Pattern match int vid (0 step) | [[:like "Tracy McGrady"->"Rudy Gay" @0 {likeness: 90}], [:like "Grant Hill"->"Tracy McGrady" @0 {likeness: 90}]] | ("Grant Hill" :player{age: 46, name: "Grant Hill"}) | | [[:like "Tracy McGrady"->"Rudy Gay" @0 {likeness: 90}], [:like "Vince Carter"->"Tracy McGrady" @0 {likeness: 90}]] | ("Vince Carter" :player{age: 42, name: "Vince Carter"}) | | [[:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}], [:like "Tiago Splitter"->"Manu Ginobili" @0 {likeness: 90}]] | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | - | [[:like "Yao Ming"->"Tracy McGrady" @0 {likeness: 90}], [:like "Yao Ming"->"Shaquile O'Neal" @0 {likeness: 90}]] | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | [[:like "Yao Ming"->"Tracy McGrady" @0 {likeness: 90}], [:like "Yao Ming"->"Shaquille O'Neal" @0 {likeness: 90}]] | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | [[:like "Tracy McGrady"->"Grant Hill" @0 {likeness: 90}], [:like "Grant Hill"->"Tracy McGrady" @0 {likeness: 90}]] | ("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"}) | | [[:like "Tracy McGrady"->"Rudy Gay" @0 {likeness: 90}], [:like "Yao Ming"->"Tracy McGrady" @0 {likeness: 90}]] | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | | [[:like "Tiago Splitter"->"Manu Ginobili" @0 {likeness: 90}], [:like "Manu Ginobili"->"Tim Duncan" @0 {likeness: 90}]] | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | @@ -271,14 +271,14 @@ Feature: Variable length Pattern match int vid (0 step) | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Marco Belinelli" :player{age: 32, name: "Marco Belinelli"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | | ("Tiago Splitter" :player{age: 34, name: "Tiago Splitter"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | diff --git a/tests/tck/features/optimizer/CollapseProjectRule.feature b/tests/tck/features/optimizer/CollapseProjectRule.feature index ded6117e92b..22712c9cb02 100644 --- a/tests/tck/features/optimizer/CollapseProjectRule.feature +++ b/tests/tck/features/optimizer/CollapseProjectRule.feature @@ -28,15 +28,12 @@ Feature: Collapse Project Rule | 4 | | 3 | And the execution plan should be: - | id | name | dependencies | operator info | - | 16 | Project | 14 | | - | 14 | Filter | 7 | | - | 7 | Project | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 18 | | - | 18 | GetVertices | 12 | | - | 12 | IndexScan | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 12 | Project | 10 | | + | 10 | Filter | 2 | | + | 2 | AppendVertices | 7 | | + | 7 | IndexScan | 0 | | + | 0 | Start | | | When profiling query: """ LOOKUP ON player diff --git a/tests/tck/features/optimizer/CombineFilterRule.feature b/tests/tck/features/optimizer/CombineFilterRule.feature index 1a8f7b807b4..08392f5c30f 100644 --- a/tests/tck/features/optimizer/CombineFilterRule.feature +++ b/tests/tck/features/optimizer/CombineFilterRule.feature @@ -19,16 +19,10 @@ Feature: combine filters | ("Vince Carter" :player{age: 42, name: "Vince Carter"}) | ("Jason Kidd" :player{age: 45, name: "Jason Kidd"}) | | ("Jason Kidd" :player{age: 45, name: "Jason Kidd"}) | ("Steve Nash" :player{age: 45, name: "Steve Nash"}) | And the execution plan should be: - | id | name | dependencies | operator info | - | 16 | Project | 18 | | - | 18 | Filter | 13 | {"condition": "(($v.age>40) AND ($n.age>42) AND !(hasSameEdgeInPath($-.__COL_0)))"} | - | 13 | Project | 12 | | - | 12 | InnerJoin | 11 | | - | 11 | Project | 20 | | - | 20 | GetVertices | 7 | | - | 7 | Filter | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 22 | | - | 22 | GetNeighbors | 17 | | - | 17 | IndexScan | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 10 | Project | 9 | | + | 9 | Filter | 3 | | + | 3 | AppendVertices | 2 | | + | 2 | Traverse | 7 | | + | 7 | IndexScan | 0 | | + | 0 | Start | | | diff --git a/tests/tck/features/optimizer/IndexScanRule.feature b/tests/tck/features/optimizer/IndexScanRule.feature index d44c5701d7e..7a5bf6e5d71 100644 --- a/tests/tck/features/optimizer/IndexScanRule.feature +++ b/tests/tck/features/optimizer/IndexScanRule.feature @@ -6,7 +6,7 @@ Feature: Match index selection Background: Given a graph with space named "nba" - Scenario: and filter embeding + Scenario: and filter embedding When profiling query: """ MATCH (v:player) @@ -20,15 +20,12 @@ Feature: Match index selection | ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | | ("Vince Carter" :player{age: 42, name: "Vince Carter"}) | And the execution plan should be: - | id | name | dependencies | operator info | - | 10 | Project | 13 | | - | 13 | Filter | 7 | | - | 7 | Project | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 15 | | - | 15 | GetVertices | 11 | | - | 11 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"RANGE","column":"name","beginValue":"\"Tim Duncan\"","endValue":"\"Yao Ming\"","includeBegin":"false","includeEnd":"true"}}} | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 9 | Project | 8 | | + | 8 | Filter | 2 | | + | 2 | AppendVertices | 6 | | + | 6 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"RANGE","column":"name","beginValue":"\"Tim Duncan\"","endValue":"\"Yao Ming\"","includeBegin":"false","includeEnd":"true"}}} | + | 0 | Start | | | When profiling query: """ MATCH (v:player) @@ -62,17 +59,14 @@ Feature: Match index selection | ("JaVale McGee" :player{age: 31, name: "JaVale McGee"}) | | ("Dwight Howard" :player{age: 33, name: "Dwight Howard"}) | And the execution plan should be: - | id | name | dependencies | operator info | - | 10 | Project | 13 | | - | 13 | Filter | 7 | | - | 7 | Project | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 15 | | - | 15 | GetVertices | 11 | | - | 11 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"RANGE","column":"age","beginValue":"30","endValue":"40","includeBegin":"false","includeEnd":"true"}}} | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 9 | Project | 8 | | + | 8 | Filter | 2 | | + | 2 | AppendVertices | 6 | | + | 6 | IndexScan | 0 | {"indexCtx": {"columnHints":{"scanType":"RANGE","column":"age","beginValue":"30","endValue":"40","includeBegin":"false","includeEnd":"true"}}} | + | 0 | Start | | | - Scenario: or filter embeding + Scenario: or filter embedding When profiling query: """ MATCH (v:player) @@ -95,17 +89,13 @@ Feature: Match index selection | ("Vince Carter" :player{age: 42, name: "Vince Carter"}) | | ("Ray Allen" :player{age: 43, name: "Ray Allen"}) | | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | - | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | And the execution plan should be: - | id | name | dependencies | operator info | - | 10 | Project | 13 | | - | 13 | Filter | 7 | {"condition":"!(hasSameEdgeInPath($-.__COL_0))"} | - | 7 | Project | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 15 | | - | 15 | GetVertices | 11 | | - | 11 | IndexScan | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 6 | Project | 2 | | + | 2 | AppendVertices | 5 | | + | 5 | IndexScan | 0 | | + | 0 | Start | | | Scenario: degenerate to full tag scan When profiling query: @@ -120,22 +110,16 @@ Feature: Match index selection | v | n | | ("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"}) | ("Grant Hill" :player{age: 46, name: "Grant Hill"}) | | ("Amar'e Stoudemire" :player{age: 36, name: "Amar'e Stoudemire"}) | ("Steve Nash" :player{age: 45, name: "Steve Nash"}) | - | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | + | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | | ("Aron Baynes" :player{age: 32, name: "Aron Baynes"}) | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | And the execution plan should be: - | id | name | dependencies | operator info | - | 16 | Project | 19 | | - | 19 | Filter | 13 | { "condition": "((($v.name<=\"Aron Baynes\") OR ($n.age>45)) AND !(hasSameEdgeInPath($-.__COL_0)))"} | - | 13 | Project | 12 | | - | 12 | InnerJoin | 11 | | - | 11 | Project | 21 | | - | 21 | GetVertices | 7 | | - | 7 | Filter | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 23 | | - | 23 | GetNeighbors | 17 | | - | 17 | IndexScan | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 9 | Project | 8 | | + | 8 | Filter | 3 | | + | 3 | AppendVertices | 2 | | + | 2 | Traverse | 1 | | + | 1 | IndexScan | 0 | | + | 0 | Start | | | # This is actually the optimization for another optRule, # but it is necessary to ensure that the current optimization does not destroy this scenario # and it can be considered in the subsequent refactoring @@ -154,16 +138,11 @@ Feature: Match index selection | count | | 81 | And the execution plan should be: - | id | name | dependencies | operator info | - | 16 | Aggregate | 18 | | - | 18 | Filter | 13 | | - | 13 | Project | 12 | | - | 12 | InnerJoin | 11 | | - | 11 | Project | 20 | | - | 20 | GetVertices | 7 | | - | 7 | Filter | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 22 | | - | 22 | GetNeighbors | 17 | | - | 17 | IndexScan | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 6 | Aggregate | 8 | | + | 8 | Project | 7 | | + | 7 | Filter | 3 | | + | 3 | AppendVertices | 2 | | + | 2 | Traverse | 1 | | + | 1 | IndexScan | 0 | | + | 0 | Start | | | diff --git a/tests/tck/features/optimizer/MergeGetNbrsDedupProjectRule.feature b/tests/tck/features/optimizer/MergeGetNbrsDedupProjectRule.feature index 9a2d37097f0..7eec224d430 100644 --- a/tests/tck/features/optimizer/MergeGetNbrsDedupProjectRule.feature +++ b/tests/tck/features/optimizer/MergeGetNbrsDedupProjectRule.feature @@ -1,6 +1,8 @@ # Copyright (c) 2021 vesoft inc. All rights reserved. # # This source code is licensed under Apache 2.0 License. +# This optimization rule is not neccessary now +@skip Feature: merge get neighbors, dedup and project rule Background: diff --git a/tests/tck/features/optimizer/MergeGetVerticesDedupProjectRule.feature b/tests/tck/features/optimizer/MergeGetVerticesDedupProjectRule.feature index a514e9009ea..02beb81b619 100644 --- a/tests/tck/features/optimizer/MergeGetVerticesDedupProjectRule.feature +++ b/tests/tck/features/optimizer/MergeGetVerticesDedupProjectRule.feature @@ -1,6 +1,8 @@ # Copyright (c) 2021 vesoft inc. All rights reserved. # # This source code is licensed under Apache 2.0 License. +# This optimization rule is not neccesarry now. +@skip Feature: merge get vertices, dedup and project rule Background: diff --git a/tests/tck/features/optimizer/PushFilterDownProjectRule.feature b/tests/tck/features/optimizer/PushFilterDownProjectRule.feature index 8dc91d38b33..6b54e7c644f 100644 --- a/tests/tck/features/optimizer/PushFilterDownProjectRule.feature +++ b/tests/tck/features/optimizer/PushFilterDownProjectRule.feature @@ -50,15 +50,15 @@ Feature: Push Filter down Project rule RETURN DISTINCT a, b, cage """ Then the result should be, in any order: - | a | b | cage | - | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | 39 | - | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | 32 | - | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | NULL | - | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | NULL | - | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | 43 | - | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | 37 | - | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | 35 | - | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | 30 | + | a | b | cage | + | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | 39 | + | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | 32 | + | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"}) | NULL | + | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | NULL | + | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | 43 | + | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | 37 | + | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | 35 | + | ("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"}) | ("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"}) | 30 | And the execution plan should be: | id | name | dependencies | operator info | | 25 | DataCollect | 24 | | diff --git a/tests/tck/features/optimizer/PushLimitDownProjectRule.feature b/tests/tck/features/optimizer/PushLimitDownProjectRule.feature index b0bc1bf4f23..4ab978c904d 100644 --- a/tests/tck/features/optimizer/PushLimitDownProjectRule.feature +++ b/tests/tck/features/optimizer/PushLimitDownProjectRule.feature @@ -22,18 +22,13 @@ Feature: Push Limit down project rule | <("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:like@0 {likeness: 95}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | | <("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:like@0 {likeness: 95}]->("Tony Parker" :player{age: 36, name: "Tony Parker"})> | And the execution plan should be: - | id | name | dependencies | operator info | - | 18 | DataCollect | 26 | | - | 26 | Project | 25 | | - | 25 | Limit | 20 | | - | 20 | Filter | 13 | | - | 13 | Project | 12 | | - | 12 | InnerJoin | 11 | | - | 11 | Project | 22 | | - | 22 | GetVertices | 7 | | - | 7 | Filter | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 24 | | - | 24 | GetNeighbors | 1 | | - | 1 | PassThrough | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 9 | DataCollect | 19 | | + | 19 | Project | 16 | | + | 16 | Limit | 11 | | + | 11 | Filter | 4 | | + | 4 | AppendVertices | 3 | | + | 3 | Traverse | 2 | | + | 2 | Dedup | 1 | | + | 1 | PassThrough | 0 | | + | 0 | Start | | | diff --git a/tests/tck/features/optimizer/RemoveUselessProjectRule.feature b/tests/tck/features/optimizer/RemoveUselessProjectRule.feature index b25f2e831c7..894c472ac73 100644 --- a/tests/tck/features/optimizer/RemoveUselessProjectRule.feature +++ b/tests/tck/features/optimizer/RemoveUselessProjectRule.feature @@ -49,17 +49,14 @@ Feature: Remove Useless Project Rule | 47 | 1 | | 48 | 1 | And the execution plan should be: - | id | name | dependencies | operator info | - | 12 | DataCollect | 11 | | - | 11 | Sort | 14 | | - | 14 | Aggregate | 8 | | - | 8 | Filter | 7 | | - | 7 | Project | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 16 | | - | 16 | GetVertices | 13 | | - | 13 | IndexScan | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 7 | DataCollect | 6 | | + | 6 | Sort | 8 | | + | 8 | Aggregate | 3 | | + | 3 | Project | 2 | | + | 2 | AppendVertices | 1 | | + | 1 | IndexScan | 0 | | + | 0 | Start | | | When profiling query: """ MATCH p = (n:player{name:"Tony Parker"}) @@ -69,11 +66,8 @@ Feature: Remove Useless Project Rule | n | p | | ("Tony Parker" :player{age: 36, name: "Tony Parker"}) | <("Tony Parker" :player{age: 36, name: "Tony Parker"})> | And the execution plan should be: - | id | name | dependencies | operator info | - | 11 | Filter | 7 | | - | 7 | Project | 6 | | - | 6 | Project | 5 | | - | 5 | Filter | 13 | | - | 13 | GetVertices | 10 | | - | 10 | IndexScan | 0 | | - | 0 | Start | | | + | id | name | dependencies | operator info | + | 6 | Project | 2 | | + | 2 | AppendVertices | 5 | | + | 5 | IndexScan | 0 | | + | 0 | Start | | | diff --git a/tests/tck/features/path/AllPath.IntVid.feature b/tests/tck/features/path/AllPath.IntVid.feature index 1fd77aabdaf..3f20e83bd1c 100644 --- a/tests/tck/features/path/AllPath.IntVid.feature +++ b/tests/tck/features/path/AllPath.IntVid.feature @@ -218,30 +218,30 @@ Feature: Integer Vid All Path WHERE (like.likeness >= 80 and like.likeness <= 90) OR (teammate.start_year is not EMPTY and teammate.start_year > 2001) UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | path | + | <("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | When executing query: """ FIND ALL PATH WITH PROP FROM hash("Tony Parker") TO hash("Yao Ming") OVER * BIDIRECT WHERE teammate.start_year > 2000 OR (like.likeness is not EMPTY AND like.likeness >= 80) UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:like@0 {likeness: 95}]-("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2001}]-("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:like@0 {likeness: 95}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2016, start_year: 2001}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | path | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:like@0 {likeness: 95}]-("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2001}]-("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:like@0 {likeness: 95}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2016, start_year: 2001}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | When executing query: """ FIND ALL PATH WITH PROP FROM hash("Yao Ming") TO hash("Danny Green") OVER * BIDIRECT WHERE like.likeness is EMPTY OR like.likeness >= 80 UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})-[:serve@0 {end_year: 2010, start_year: 2009}]->("Cavaliers" :team{name: "Cavaliers"})<-[:serve@0 {end_year: 2010, start_year: 2009}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | - | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})-[:like@0 {likeness: 80}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:teammate@0 {end_year: 2016, start_year: 2010}]->("Danny Green" :player{age: 31, name: "Danny Green"})> | - | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2000, start_year: 1997}]->("Raptors" :team{name: "Raptors"})<-[:serve@0 {end_year: 2019, start_year: 2018}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | - | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs" :team{name: "Spurs"})<-[:serve@0 {end_year: 2018, start_year: 2010}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | + | path | + | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})-[:serve@0 {end_year: 2010, start_year: 2009}]->("Cavaliers" :team{name: "Cavaliers"})<-[:serve@0 {end_year: 2010, start_year: 2009}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | + | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})-[:like@0 {likeness: 80}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:teammate@0 {end_year: 2016, start_year: 2010}]->("Danny Green" :player{age: 31, name: "Danny Green"})> | + | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2000, start_year: 1997}]->("Raptors" :team{name: "Raptors"})<-[:serve@0 {end_year: 2019, start_year: 2018}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | + | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs" :team{name: "Spurs"})<-[:serve@0 {end_year: 2018, start_year: 2010}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | Scenario: Integer Vid Dangling edge Given an empty graph diff --git a/tests/tck/features/path/AllPath.feature b/tests/tck/features/path/AllPath.feature index cd188774c7e..a73a28fc1f7 100644 --- a/tests/tck/features/path/AllPath.feature +++ b/tests/tck/features/path/AllPath.feature @@ -218,30 +218,30 @@ Feature: All Path WHERE (like.likeness >= 80 and like.likeness <= 90) OR (teammate.start_year is not EMPTY and teammate.start_year > 2001) UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | path | + | <("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | When executing query: """ FIND ALL PATH WITH PROP FROM "Tony Parker" TO "Yao Ming" OVER * BIDIRECT WHERE teammate.start_year > 2000 OR (like.likeness is not EMPTY AND like.likeness >= 80) UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:like@0 {likeness: 95}]-("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2001}]-("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:like@0 {likeness: 95}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2016, start_year: 2001}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | path | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:like@0 {likeness: 95}]-("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2001}]-("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:like@0 {likeness: 95}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2016, start_year: 2001}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})<-[:like@0 {likeness: 80}]-("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})<-[:like@0 {likeness: 90}]-("Yao Ming" :player{age: 38, name: "Yao Ming"})> | When executing query: """ FIND ALL PATH WITH PROP FROM "Yao Ming" TO "Danny Green" OVER * BIDIRECT WHERE like.likeness is EMPTY OR like.likeness >= 80 UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})-[:serve@0 {end_year: 2010, start_year: 2009}]->("Cavaliers" :team{name: "Cavaliers"})<-[:serve@0 {end_year: 2010, start_year: 2009}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | - | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})-[:like@0 {likeness: 80}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:teammate@0 {end_year: 2016, start_year: 2010}]->("Danny Green" :player{age: 31, name: "Danny Green"})> | - | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2000, start_year: 1997}]->("Raptors" :team{name: "Raptors"})<-[:serve@0 {end_year: 2019, start_year: 2018}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | - | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs" :team{name: "Spurs"})<-[:serve@0 {end_year: 2018, start_year: 2010}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | + | path | + | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})-[:serve@0 {end_year: 2010, start_year: 2009}]->("Cavaliers" :team{name: "Cavaliers"})<-[:serve@0 {end_year: 2010, start_year: 2009}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | + | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})-[:like@0 {likeness: 80}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:teammate@0 {end_year: 2016, start_year: 2010}]->("Danny Green" :player{age: 31, name: "Danny Green"})> | + | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2000, start_year: 1997}]->("Raptors" :team{name: "Raptors"})<-[:serve@0 {end_year: 2019, start_year: 2018}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | + | <("Yao Ming" :player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs" :team{name: "Spurs"})<-[:serve@0 {end_year: 2018, start_year: 2010}]-("Danny Green" :player{age: 31, name: "Danny Green"})> | Scenario: Dangling edge Given an empty graph diff --git a/tests/tck/features/path/ShortestPath.IntVid.feature b/tests/tck/features/path/ShortestPath.IntVid.feature index 701baf08f69..47f71eaef0d 100644 --- a/tests/tck/features/path/ShortestPath.IntVid.feature +++ b/tests/tck/features/path/ShortestPath.IntVid.feature @@ -94,10 +94,10 @@ Feature: Integer Vid Shortest Path """ Then the result should be, in any order, with relax comparison: | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | | <("Tony Parker")-[:like]->("Tim Duncan")-[:teammate]->("Danny Green")-[:like]->("LeBron James")-[:serve]->("Lakers")> | | <("Tony Parker")-[:teammate]->("Tim Duncan")-[:teammate]->("Danny Green")-[:like]->("LeBron James")-[:serve]->("Lakers")> | | <("Tony Parker")-[:like]->("Manu Ginobili")> | @@ -110,23 +110,23 @@ Feature: Integer Vid Shortest Path FIND SHORTEST PATH FROM hash("Tony Parker"), hash("Yao Ming") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:like]->("Manu Ginobili")> | - | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | - | <("Tony Parker")-[:serve]->("Spurs")> | + | path | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:like]->("Manu Ginobili")> | + | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | + | <("Tony Parker")-[:serve]->("Spurs")> | When executing query: """ FIND SHORTEST PATH FROM hash("Yao Ming") TO hash("Tim Duncan"), hash("Spurs"), hash("Lakers") OVER * UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")> | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | + | path | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | Scenario: Integer Vid [5] MultiPair Shortest Path When executing query: @@ -136,7 +136,7 @@ Feature: Integer Vid Shortest Path Then the result should be, in any order, with relax comparison: | path | | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | | <("Marco Belinelli")-[:like]->("Danny Green")-[:like]->("LeBron James")-[:serve]->("Lakers")> | | <("Marco Belinelli")-[:serve]->("Spurs")> | | <("Marco Belinelli")-[:serve@1]->("Spurs")> | @@ -169,42 +169,42 @@ Feature: Integer Vid Shortest Path FIND SHORTEST PATH FROM hash("Yao Ming") TO hash("Tony Parker"), hash("Tracy McGrady") OVER like,serve UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | - | <("Yao Ming")-[:like]->("Tracy McGrady")> | + | path | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")> | Scenario: Integer Vid [9] MultiPair Shortest Path When executing query: """ - FIND SHORTEST PATH FROM hash("Shaquile O\'Neal") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * UPTO 5 STEPS + FIND SHORTEST PATH FROM hash("Shaquille O\'Neal") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:serve]->("Spurs")> | - | <("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:serve]->("Spurs")> | + | <("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | Scenario: Integer Vid [10] MultiPair Shortest Path When executing query: """ - FIND SHORTEST PATH FROM hash("Shaquile O\'Neal"), hash("Nobody") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * UPTO 5 STEPS + FIND SHORTEST PATH FROM hash("Shaquille O\'Neal"), hash("Nobody") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:serve]->("Spurs")> | - | <("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:serve]->("Spurs")> | + | <("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | Scenario: Integer Vid [11] MultiPair Shortest Path When executing query: """ - FIND SHORTEST PATH FROM hash("Shaquile O\'Neal") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER like UPTO 5 STEPS + FIND SHORTEST PATH FROM hash("Shaquille O\'Neal") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER like UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | Scenario: Integer Vid [12] MultiPair Shortest Path When executing query: @@ -232,30 +232,30 @@ Feature: Integer Vid Shortest Path | FIND SHORTEST PATH FROM $-.src TO $-.dst OVER like, serve UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | + | path | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | Scenario: Integer Vid [2] MultiPair Shortest Path Run Time input When executing query: """ - YIELD hash("Shaquile O\'Neal") AS src + YIELD hash("Shaquille O\'Neal") AS src | FIND SHORTEST PATH FROM $-.src TO hash("Manu Ginobili") OVER * UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | Scenario: Integer Vid [3] MultiPair Shortest Path Run Time input When executing query: """ YIELD hash("Manu Ginobili") AS dst - | FIND SHORTEST PATH FROM hash("Shaquile O\'Neal") TO $-.dst OVER * UPTO 5 STEPS + | FIND SHORTEST PATH FROM hash("Shaquille O\'Neal") TO $-.dst OVER * UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | Scenario: Integer Vid [4] MultiPair Shortest Path Run Time input When executing query: @@ -266,7 +266,7 @@ Feature: Integer Vid Shortest Path Then the result should be, in any order, with relax comparison: | path | | <("Tracy McGrady")-[:like]->("Rudy Gay")-[:like]->("LaMarcus Aldridge")-[:like]->("Tony Parker")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | Scenario: Integer Vid [5] MultiPair Shortest Path Run Time input When executing query: @@ -277,7 +277,7 @@ Feature: Integer Vid Shortest Path Then the result should be, in any order, with relax comparison: | path | | <("Tracy McGrady")-[:like]->("Rudy Gay")-[:like]->("LaMarcus Aldridge")-[:like]->("Tony Parker")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | Scenario: Integer Vid [6] MultiPair Shortest Path Run Time input When executing query: @@ -324,13 +324,13 @@ Feature: Integer Vid Shortest Path Scenario: Integer Vid [2] Shortest Path With Limit When executing query: """ - FIND SHORTEST PATH FROM hash("Shaquile O\'Neal"), hash("Nobody") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * UPTO 5 STEPS + FIND SHORTEST PATH FROM hash("Shaquille O\'Neal"), hash("Nobody") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * UPTO 5 STEPS | ORDER BY $-.path | LIMIT 2 """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | Scenario: Integer Vid [3] Shortest Path With Limit When executing query: @@ -413,13 +413,13 @@ Feature: Integer Vid Shortest Path FIND SHORTEST PATH FROM hash("Tony Parker"), hash("Yao Ming") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * BIDIRECT UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:serve]->("Spurs")> | - | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | - | <("Tony Parker")-[:like]->("Manu Ginobili")> | - | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Spurs")> | + | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | + | <("Tony Parker")-[:like]->("Manu Ginobili")> | + | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | Scenario: Integer Vid [3] Shortest Path BIDIRECT When executing query: @@ -427,25 +427,25 @@ Feature: Integer Vid Shortest Path FIND SHORTEST PATH FROM hash("Tony Parker"), hash("Yao Ming") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * BIDIRECT UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")<-[:serve]-("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")<-[:like]-("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")<-[:teammate]-("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Tony Parker")<-[:like]-("Tim Duncan")<-[:like]-("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")<-[:teammate]-("Tim Duncan")<-[:like]-("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:like]->("Tim Duncan")<-[:like]-("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:teammate]->("Tim Duncan")<-[:like]-("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")<-[:like]-("Dejounte Murray")-[:like]->("LeBron James")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:serve]->("Spurs")<-[:serve]-("Paul Gasol")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:serve]->("Hornets")<-[:serve]-("Dwight Howard")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:serve]->("Spurs")> | - | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | - | <("Tony Parker")-[:like]->("Manu Ginobili")> | - | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")<-[:serve]-("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")<-[:like]-("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")<-[:teammate]-("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Tony Parker")<-[:like]-("Tim Duncan")<-[:like]-("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")<-[:teammate]-("Tim Duncan")<-[:like]-("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:like]->("Tim Duncan")<-[:like]-("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:teammate]->("Tim Duncan")<-[:like]-("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")<-[:like]-("Dejounte Murray")-[:like]->("LeBron James")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Spurs")<-[:serve]-("Paul Gasol")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Hornets")<-[:serve]-("Dwight Howard")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Spurs")> | + | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | + | <("Tony Parker")-[:like]->("Manu Ginobili")> | + | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | Scenario: Integer Vid Shortest Path With PROP When executing query: @@ -467,13 +467,13 @@ Feature: Integer Vid Shortest Path FIND SHORTEST PATH WITH PROP FROM hash("Tony Parker"), hash("Yao Ming") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * BIDIRECT UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquile O'Neal": player{age: 47, name: "Shaquile O'Neal"})-[:serve@0 {end_year: 2004,start_year: 1996}]->("Lakers": team{name: "Lakers"})> | - | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady": player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs": team{name: "Spurs"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("Spurs" :team{name: "Spurs"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2002}]-("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:like@0 {likeness: 95}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2018, start_year: 2002}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | path | + | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquille O'Neal": player{age: 47, name: "Shaquille O'Neal"})-[:serve@0 {end_year: 2004,start_year: 1996}]->("Lakers": team{name: "Lakers"})> | + | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady": player{age: 39, name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs": team{name: "Spurs"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("Spurs" :team{name: "Spurs"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2002}]-("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:like@0 {likeness: 95}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2018, start_year: 2002}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | Scenario: Integer Vid Shortest Path With Filter When executing query: @@ -481,12 +481,12 @@ Feature: Integer Vid Shortest Path FIND SHORTEST PATH WITH PROP FROM hash("Tony Parker"), hash("Yao Ming") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * BIDIRECT WHERE like.likeness == 90 OR like.likeness is empty UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquile O'Neal" :player {age: 47,name: "Shaquile O'Neal"})-[:serve@0 {end_year: 2004, start_year: 1996}]->("Lakers": team{name: "Lakers"})> | - | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady": player{age: 39,name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs": team{name: "Spurs"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("Spurs" :team{name: "Spurs"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2002}]-("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2018, start_year: 2002}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | path | + | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquille O'Neal" :player {age: 47,name: "Shaquille O'Neal"})-[:serve@0 {end_year: 2004, start_year: 1996}]->("Lakers": team{name: "Lakers"})> | + | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady": player{age: 39,name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs": team{name: "Spurs"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("Spurs" :team{name: "Spurs"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2002}]-("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2018, start_year: 2002}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | When executing query: """ FIND SHORTEST PATH WITH PROP FROM hash("Tony Parker"), hash("Yao Ming") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * REVERSELY WHERE like.likeness > 70 @@ -502,7 +502,7 @@ Feature: Integer Vid Shortest Path Then the result should be, in any order, with relax comparison: | path | | <("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:like@0 {likeness: 90}]->("Rudy Gay" :player{age: 32, name: "Rudy Gay"})-[:like@0 {likeness: 70}]->("LaMarcus Aldridge" :player{age: 33, name: "LaMarcus Aldridge"})-[:like@0 {likeness: 75}]->("Tony Parker" :player{age: 36, name: "Tony Parker"})> | - | <("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})-[:like@0 {likeness: 80}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:like@0 {likeness: 95}]->("Tony Parker" :player{age: 36, name: "Tony Parker"})> | + | <("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})-[:like@0 {likeness: 80}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:like@0 {likeness: 95}]->("Tony Parker" :player{age: 36, name: "Tony Parker"})> | When executing query: """ FIND SHORTEST PATH WITH PROP FROM hash("Tony Parker"), hash("Yao Ming") TO hash("Manu Ginobili"), hash("Spurs"), hash("Lakers") OVER * BIDIRECT WHERE teammate.start_year is not EMPTY OR like.likeness > 90 UPTO 3 STEPS diff --git a/tests/tck/features/path/ShortestPath.feature b/tests/tck/features/path/ShortestPath.feature index bffd7b3bcaa..55587e0d76a 100644 --- a/tests/tck/features/path/ShortestPath.feature +++ b/tests/tck/features/path/ShortestPath.feature @@ -94,10 +94,10 @@ Feature: Shortest Path """ Then the result should be, in any order, with relax comparison: | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | | <("Tony Parker")-[:like]->("Tim Duncan")-[:teammate]->("Danny Green")-[:like]->("LeBron James")-[:serve]->("Lakers")> | | <("Tony Parker")-[:teammate]->("Tim Duncan")-[:teammate]->("Danny Green")-[:like]->("LeBron James")-[:serve]->("Lakers")> | | <("Tony Parker")-[:like]->("Manu Ginobili")> | @@ -110,23 +110,23 @@ Feature: Shortest Path FIND SHORTEST PATH FROM "Tony Parker", "Yao Ming" TO "Manu Ginobili", "Spurs", "Lakers" OVER * UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:like]->("Manu Ginobili")> | - | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | - | <("Tony Parker")-[:serve]->("Spurs")> | + | path | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:like]->("Manu Ginobili")> | + | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | + | <("Tony Parker")-[:serve]->("Spurs")> | When executing query: """ FIND SHORTEST PATH FROM "Yao Ming" TO "Tim Duncan", "Spurs", "Lakers" OVER * UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")> | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | + | path | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | Scenario: [5] MultiPair Shortest Path When executing query: @@ -136,7 +136,7 @@ Feature: Shortest Path Then the result should be, in any order, with relax comparison: | path | | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | | <("Marco Belinelli")-[:like]->("Danny Green")-[:like]->("LeBron James")-[:serve]->("Lakers")> | | <("Marco Belinelli")-[:serve]->("Spurs")> | | <("Marco Belinelli")-[:serve@1]->("Spurs")> | @@ -169,42 +169,42 @@ Feature: Shortest Path FIND SHORTEST PATH FROM "Yao Ming" TO "Tony Parker","Tracy McGrady" OVER like,serve UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | - | <("Yao Ming")-[:like]->("Tracy McGrady")> | + | path | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")> | Scenario: [9] MultiPair Shortest Path When executing query: """ - FIND SHORTEST PATH FROM "Shaquile O\'Neal" TO "Manu Ginobili", "Spurs", "Lakers" OVER * UPTO 5 STEPS + FIND SHORTEST PATH FROM "Shaquille O\'Neal" TO "Manu Ginobili", "Spurs", "Lakers" OVER * UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:serve]->("Spurs")> | - | <("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:serve]->("Spurs")> | + | <("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | Scenario: [10] MultiPair Shortest Path When executing query: """ - FIND SHORTEST PATH FROM "Shaquile O\'Neal", "Nobody" TO "Manu Ginobili", "Spurs", "Lakers" OVER * UPTO 5 STEPS + FIND SHORTEST PATH FROM "Shaquille O\'Neal", "Nobody" TO "Manu Ginobili", "Spurs", "Lakers" OVER * UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:serve]->("Spurs")> | - | <("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:serve]->("Spurs")> | + | <("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | Scenario: [11] MultiPair Shortest Path When executing query: """ - FIND SHORTEST PATH FROM "Shaquile O\'Neal" TO "Manu Ginobili", "Spurs", "Lakers" OVER like UPTO 5 STEPS + FIND SHORTEST PATH FROM "Shaquille O\'Neal" TO "Manu Ginobili", "Spurs", "Lakers" OVER like UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | Scenario: [12] MultiPair Shortest Path When executing query: @@ -232,30 +232,30 @@ Feature: Shortest Path | FIND SHORTEST PATH FROM $-.src TO $-.dst OVER like, serve UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | + | path | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | Scenario: [2] MultiPair Shortest Path Run Time input When executing query: """ - YIELD "Shaquile O\'Neal" AS src + YIELD "Shaquille O\'Neal" AS src | FIND SHORTEST PATH FROM $-.src TO "Manu Ginobili" OVER * UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | Scenario: [3] MultiPair Shortest Path Run Time input When executing query: """ YIELD "Manu Ginobili" AS dst - | FIND SHORTEST PATH FROM "Shaquile O\'Neal" TO $-.dst OVER * UPTO 5 STEPS + | FIND SHORTEST PATH FROM "Shaquille O\'Neal" TO $-.dst OVER * UPTO 5 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | Scenario: [4] MultiPair Shortest Path Run Time input When executing query: @@ -266,7 +266,7 @@ Feature: Shortest Path Then the result should be, in any order, with relax comparison: | path | | <("Tracy McGrady")-[:like]->("Rudy Gay")-[:like]->("LaMarcus Aldridge")-[:like]->("Tony Parker")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | Scenario: [5] MultiPair Shortest Path Run Time input When executing query: @@ -277,7 +277,7 @@ Feature: Shortest Path Then the result should be, in any order, with relax comparison: | path | | <("Tracy McGrady")-[:like]->("Rudy Gay")-[:like]->("LaMarcus Aldridge")-[:like]->("Tony Parker")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Tony Parker")> | Scenario: [6] MultiPair Shortest Path Run Time input When executing query: @@ -324,13 +324,13 @@ Feature: Shortest Path Scenario: [2] Shortest Path With Limit When executing query: """ - FIND SHORTEST PATH FROM "Shaquile O\'Neal", "Nobody" TO "Manu Ginobili", "Spurs", "Lakers" OVER * UPTO 5 STEPS + FIND SHORTEST PATH FROM "Shaquille O\'Neal", "Nobody" TO "Manu Ginobili", "Spurs", "Lakers" OVER * UPTO 5 STEPS | ORDER BY $-.path | LIMIT 2 """ Then the result should be, in any order, with relax comparison: - | path | - | <("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | path | + | <("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | Scenario: [3] Shortest Path With Limit When executing query: @@ -413,13 +413,13 @@ Feature: Shortest Path FIND SHORTEST PATH FROM "Tony Parker", "Yao Ming" TO "Manu Ginobili", "Spurs", "Lakers" OVER * BIDIRECT UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:serve]->("Spurs")> | - | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | - | <("Tony Parker")-[:like]->("Manu Ginobili")> | - | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Spurs")> | + | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | + | <("Tony Parker")-[:like]->("Manu Ginobili")> | + | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | Scenario: [3] Shortest Path BIDIRECT When executing query: @@ -427,25 +427,25 @@ Feature: Shortest Path FIND SHORTEST PATH FROM "Tony Parker", "Yao Ming" TO "Manu Ginobili", "Spurs", "Lakers" OVER * BIDIRECT UPTO 3 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")<-[:serve]-("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")<-[:like]-("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:like]->("Tim Duncan")<-[:teammate]-("Manu Ginobili")> | - | <("Yao Ming")-[:like]->("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | - | <("Tony Parker")<-[:like]-("Tim Duncan")<-[:like]-("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")<-[:teammate]-("Tim Duncan")<-[:like]-("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:like]->("Tim Duncan")<-[:like]-("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:teammate]->("Tim Duncan")<-[:like]-("Shaquile O'Neal")-[:serve]->("Lakers")> | - | <("Tony Parker")<-[:like]-("Dejounte Murray")-[:like]->("LeBron James")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:serve]->("Spurs")<-[:serve]-("Paul Gasol")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:serve]->("Hornets")<-[:serve]-("Dwight Howard")-[:serve]->("Lakers")> | - | <("Tony Parker")-[:serve]->("Spurs")> | - | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | - | <("Tony Parker")-[:like]->("Manu Ginobili")> | - | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | + | path | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")<-[:serve]-("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")<-[:like]-("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:like]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")-[:teammate]->("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:like]->("Tim Duncan")<-[:teammate]-("Manu Ginobili")> | + | <("Yao Ming")-[:like]->("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Yao Ming")-[:like]->("Tracy McGrady")-[:serve]->("Spurs")> | + | <("Tony Parker")<-[:like]-("Tim Duncan")<-[:like]-("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")<-[:teammate]-("Tim Duncan")<-[:like]-("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:like]->("Tim Duncan")<-[:like]-("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:teammate]->("Tim Duncan")<-[:like]-("Shaquille O'Neal")-[:serve]->("Lakers")> | + | <("Tony Parker")<-[:like]-("Dejounte Murray")-[:like]->("LeBron James")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Spurs")<-[:serve]-("Paul Gasol")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Hornets")<-[:serve]-("Dwight Howard")-[:serve]->("Lakers")> | + | <("Tony Parker")-[:serve]->("Spurs")> | + | <("Tony Parker")<-[:teammate]-("Manu Ginobili")> | + | <("Tony Parker")-[:like]->("Manu Ginobili")> | + | <("Tony Parker")-[:teammate]->("Manu Ginobili")> | Scenario: Shortest Path With PROP When executing query: @@ -467,13 +467,13 @@ Feature: Shortest Path FIND SHORTEST PATH WITH PROP FROM "Tony Parker", "Yao Ming" TO "Manu Ginobili", "Spurs", "Lakers" OVER * BIDIRECT UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquile O'Neal" :player {age: 47,name: "Shaquile O'Neal"})-[:serve@0 {end_year: 2004, start_year: 1996}]->("Lakers": team{name: "Lakers"})> | - | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady": player{age: 39,name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs": team{name: "Spurs"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("Spurs" :team{name: "Spurs"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2002}]-("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:like@0 {likeness: 95}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2018, start_year: 2002}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | path | + | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquille O'Neal" :player {age: 47,name: "Shaquille O'Neal"})-[:serve@0 {end_year: 2004, start_year: 1996}]->("Lakers": team{name: "Lakers"})> | + | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady": player{age: 39,name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs": team{name: "Spurs"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("Spurs" :team{name: "Spurs"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2002}]-("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:like@0 {likeness: 95}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2018, start_year: 2002}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | Scenario: Shortest Path With Filter When executing query: @@ -481,12 +481,12 @@ Feature: Shortest Path FIND SHORTEST PATH WITH PROP FROM "Tony Parker", "Yao Ming" TO "Manu Ginobili", "Spurs", "Lakers" OVER * BIDIRECT WHERE like.likeness == 90 OR like.likeness is empty UPTO 2 STEPS """ Then the result should be, in any order, with relax comparison: - | path | - | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquile O'Neal" :player {age: 47,name: "Shaquile O'Neal"})-[:serve@0 {end_year: 2004, start_year: 1996}]->("Lakers": team{name: "Lakers"})> | - | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady": player{age: 39,name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs": team{name: "Spurs"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("Spurs" :team{name: "Spurs"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2002}]-("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | - | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2018, start_year: 2002}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | path | + | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Shaquille O'Neal" :player {age: 47,name: "Shaquille O'Neal"})-[:serve@0 {end_year: 2004, start_year: 1996}]->("Lakers": team{name: "Lakers"})> | + | <("Yao Ming" : player{age: 38, name: "Yao Ming"})-[:like@0 {likeness: 90}]->("Tracy McGrady": player{age: 39,name: "Tracy McGrady"})-[:serve@0 {end_year: 2013, start_year: 2013}]->("Spurs": team{name: "Spurs"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("Spurs" :team{name: "Spurs"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})<-[:teammate@0 {end_year: 2016, start_year: 2002}]-("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | + | <("Tony Parker" :player{age: 36, name: "Tony Parker"})-[:teammate@0 {end_year: 2018, start_year: 2002}]->("Manu Ginobili" :player{age: 41, name: "Manu Ginobili"})> | When executing query: """ FIND SHORTEST PATH WITH PROP FROM "Tony Parker", "Yao Ming" TO "Manu Ginobili", "Spurs", "Lakers" OVER * REVERSELY WHERE like.likeness > 70 @@ -502,7 +502,7 @@ Feature: Shortest Path Then the result should be, in any order, with relax comparison: | path | | <("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"})-[:like@0 {likeness: 90}]->("Rudy Gay" :player{age: 32, name: "Rudy Gay"})-[:like@0 {likeness: 70}]->("LaMarcus Aldridge" :player{age: 33, name: "LaMarcus Aldridge"})-[:like@0 {likeness: 75}]->("Tony Parker" :player{age: 36, name: "Tony Parker"})> | - | <("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"})-[:like@0 {likeness: 80}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:like@0 {likeness: 95}]->("Tony Parker" :player{age: 36, name: "Tony Parker"})> | + | <("Shaquille O'Neal" :player{age: 47, name: "Shaquille O'Neal"})-[:like@0 {likeness: 80}]->("Tim Duncan" :bachelor{name: "Tim Duncan", speciality: "psychology"} :player{age: 42, name: "Tim Duncan"})-[:like@0 {likeness: 95}]->("Tony Parker" :player{age: 36, name: "Tony Parker"})> | When executing query: """ FIND SHORTEST PATH WITH PROP FROM "Tony Parker", "Yao Ming" TO "Manu Ginobili", "Spurs", "Lakers" OVER * BIDIRECT WHERE teammate.start_year is not EMPTY OR like.likeness > 90 UPTO 3 STEPS diff --git a/tests/tck/features/schema/Comment.feature b/tests/tck/features/schema/Comment.feature index ebb69b54b62..f877007f633 100644 --- a/tests/tck/features/schema/Comment.feature +++ b/tests/tck/features/schema/Comment.feature @@ -224,6 +224,6 @@ Feature: Schema Comment | "test_comment_edge_index" | 'CREATE EDGE INDEX `test_comment_edge_index` ON `test_comment_edge` (\n `name`(8)\n) comment = "The edge index of person name."' | Examples: - | tag_of_person_comment | tag_of_person_comment_modified | edge_of_person_comment | edge_of_person_comment_modified | - | "The tag of person infomation." | "The tag of person infomation modified." | "The edge of person information." | "The edge of person infomation modified." | - | "个人信息标签。" | "修改过的个人信息标签。" | "个人信息边。" | "修改过的个人信息边。" | + | tag_of_person_comment | tag_of_person_comment_modified | edge_of_person_comment | edge_of_person_comment_modified | + | "The tag of person information." | "The tag of person information modified." | "The edge of person information." | "The edge of person information modified." | + | "个人信息标签。" | "修改过的个人信息标签。" | "个人信息边。" | "修改过的个人信息边。" | diff --git a/tests/tck/features/schema/Schema.feature b/tests/tck/features/schema/Schema.feature index 2a65858dda1..252c3589bf6 100644 --- a/tests/tck/features/schema/Schema.feature +++ b/tests/tck/features/schema/Schema.feature @@ -270,7 +270,7 @@ Feature: Insert string vid of vertex and edge """ CREATE EDGE buy_type_mismatch(id int, time_ string DEFAULT 0) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # existent edge When executing query: """ @@ -661,37 +661,37 @@ Feature: Insert string vid of vertex and edge """ ALTER TAG tag_not_null_default1 ADD (col1 string DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter tag with wrong type default value of timestamp when add When executing query: """ ALTER TAG tag_not_null_default1 ADD (col1 timestamp DEFAULT -10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter tag with wrong type default value of float when add When executing query: """ ALTER TAG tag_not_null_default1 ADD (col1 float DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter tag with wrong type default value of bool when add When executing query: """ ALTER TAG tag_not_null_default1 ADD (col1 bool DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter tag with wrong type default value of int8 when add When executing query: """ ALTER TAG tag_not_null_default1 ADD (col1 int8 DEFAULT 10000) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter tag with wrong type default value of time when add When executing query: """ ALTER TAG tag_not_null_default1 ADD (col1 time DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter tag with out of rang string default value of fixed_string when add When executing query: """ @@ -711,44 +711,44 @@ Feature: Insert string vid of vertex and edge """ ALTER TAG tag_not_null_default1 CHANGE (name FIXED_STRING(10) DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter edge with wrong type default value of string when add When executing query: """ CREATE EDGE edge_not_null_default1(name string NOT NULL DEFAULT "N/A"); ALTER EDGE edge_not_null_default1 ADD (col1 string DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter edge with wrong type default value of timestamp when add When executing query: """ ALTER EDGE edge_not_null_default1 ADD (col1 timestamp DEFAULT -10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter edge with wrong type default value of float when add When executing query: """ ALTER EDGE edge_not_null_default1 ADD (col1 float DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter edge with wrong type default value of bool when add When executing query: """ ALTER EDGE edge_not_null_default1 ADD (col1 bool DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter edge with wrong type default value of int8 when add When executing query: """ ALTER EDGE edge_not_null_default1 ADD (col1 int8 DEFAULT 10000) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter edge with wrong type default value of time when add When executing query: """ ALTER EDGE edge_not_null_default1 ADD (col1 time DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! # test alter edge with out of rang string default value of fixed_string when add When executing query: """ @@ -768,7 +768,7 @@ Feature: Insert string vid of vertex and edge """ ALTER EDGE edge_not_null_default1 CHANGE (name FIXED_STRING(10) DEFAULT 10) """ - Then a ExecutionError should be raised at runtime: Invalid parm! + Then a ExecutionError should be raised at runtime: Invalid param! When executing query: """ DROP SPACE issue2009; diff --git a/tests/tck/features/subgraph/subgraph.IntVid.feature b/tests/tck/features/subgraph/subgraph.IntVid.feature index d2bd7b278bb..5c510feec24 100644 --- a/tests/tck/features/subgraph/subgraph.IntVid.feature +++ b/tests/tck/features/subgraph/subgraph.IntVid.feature @@ -19,7 +19,7 @@ Feature: Integer Vid subgraph Then a SemanticError should be raised at runtime: `$a.id', not exist variable `a' When executing query: """ - GET SUBGRAPH WITH PROP FROM hash("Tim Duncan") YIELD vertexs + GET SUBGRAPH WITH PROP FROM hash("Tim Duncan") YIELD invalidColumn """ Then a SemanticError should be raised at runtime: Get Subgraph only support YIELD vertices OR edges When executing query: @@ -120,12 +120,12 @@ Feature: Integer Vid subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Tony Parker"->"Manu Ginobili"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:serve "Manu Ginobili"->"Spurs"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:serve "Manu Ginobili"->"Spurs"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Boris Diaw"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Dejounte Murray"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Dejounte Murray"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | @@ -157,12 +157,12 @@ Feature: Integer Vid subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | ("Pistons") | [:serve "LeBron James"->"Cavaliers"@1] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"LeBron James"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Danny Green"->"Marco Belinelli"@0] | ("Kings") | [:serve "Rudy Gay"->"Kings"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | ("Raptors") | [:serve "Cory Joseph"->"Raptors"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | ("Raptors") | [:serve "Cory Joseph"->"Raptors"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:serve "Danny Green"->"Raptors"@0] | ("Jazz") | [:serve "Rudy Gay"->"Raptors"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:serve "Danny Green"->"Spurs"@0] | ("LeBron James") | [:serve "Tracy McGrady"->"Raptors"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Paul Gasol") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("Kyle Anderson") | [:serve "LeBron James"->"Heat"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Rudy Gay") | [:serve "LeBron James"->"Lakers"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Rudy Gay") | [:serve "LeBron James"->"Lakers"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Paul Gasol"->"Bulls"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:serve "Manu Ginobili"->"Spurs"@0] | ("Yao Ming") | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("James Harden") | [:like "Tracy McGrady"->"Rudy Gay"@0] | @@ -175,14 +175,14 @@ Feature: Integer Vid subgraph | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Heat") | [:serve "David West"->"Warriors"@0] | | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Lakers") | [:serve "Jonathon Simmons"->"76ers"@0] | | | | [:serve "Boris Diaw"->"Suns"@0] | ("Suns") | [:serve "Jonathon Simmons"->"Magic"@0] | - | | | [:like "Yao Ming"->"Shaquile O\'Neal"@0] | ("Magic") | [:serve "JaVale McGee"->"Lakers"@0] | - | | | [:like "Shaquile O\'Neal"->"JaVale McGee"@0] | ("Trail Blazers") | [:serve "Tracy McGrady"->"Magic"@0] | - | | | [:serve "Shaquile O\'Neal"->"Cavaliers"@0] | ("76ers") | [:serve "JaVale McGee"->"Warriors"@0] | - | | | [:serve "Shaquile O\'Neal"->"Celtics"@0] | ("JaVale McGee") | | - | | | [:serve "Shaquile O\'Neal"->"Heat"@0] | ("Cory Joseph") | | - | | | [:serve "Shaquile O\'Neal"->"Lakers"@0] | ("Tracy McGrady") | | - | | | [:serve "Shaquile O\'Neal"->"Magic"@0] | ("Russell Westbrook") | | - | | | [:serve "Shaquile O\'Neal"->"Suns"@0] | ("Bulls") | | + | | | [:like "Yao Ming"->"Shaquille O\'Neal"@0] | ("Magic") | [:serve "JaVale McGee"->"Lakers"@0] | + | | | [:like "Shaquille O\'Neal"->"JaVale McGee"@0] | ("Trail Blazers") | [:serve "Tracy McGrady"->"Magic"@0] | + | | | [:serve "Shaquille O\'Neal"->"Cavaliers"@0] | ("76ers") | [:serve "JaVale McGee"->"Warriors"@0] | + | | | [:serve "Shaquille O\'Neal"->"Celtics"@0] | ("JaVale McGee") | | + | | | [:serve "Shaquille O\'Neal"->"Heat"@0] | ("Cory Joseph") | | + | | | [:serve "Shaquille O\'Neal"->"Lakers"@0] | ("Tracy McGrady") | | + | | | [:serve "Shaquille O\'Neal"->"Magic"@0] | ("Russell Westbrook") | | + | | | [:serve "Shaquille O\'Neal"->"Suns"@0] | ("Bulls") | | | | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Warriors") | | | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | @@ -240,14 +240,14 @@ Feature: Integer Vid subgraph | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Danny Green") | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | ("Yao Ming") | | [:like "Danny Green"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | ("Rudy Gay") | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | | - | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Marco Belinelli"->"Danny Green"@0] | | + | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Marco Belinelli"->"Danny Green"@0] | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Danny Green"->"Marco Belinelli"@0] | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Tim Duncan"->"Manu Ginobili"@0] | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | [:like "Boris Diaw"->"Tony Parker"@0] | | | | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | @@ -274,7 +274,7 @@ Feature: Integer Vid subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Aron Baynes") | [:serve "Danny Green"->"Cavaliers"@0] | ("Bulls") | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Manu Ginobili") | [:serve "Danny Green"->"Raptors"@0] | ("Trail Blazers") | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Danny Green"->"Spurs"@0] | ("Celtics") | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Danny Green"@0] | ("Kings") | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Danny Green"@0] | ("Kings") | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Marco Belinelli"->"Danny Green"@0] | ("Hawks") | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Spurs") | [:serve "Marco Belinelli"->"76ers"@0] | ("Warriors") | | | | | [:serve "Marco Belinelli"->"Bulls"@0] | ("Cavaliers") | | @@ -305,13 +305,13 @@ Feature: Integer Vid subgraph | | | [:serve "Tiago Splitter"->"76ers"@0] | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Celtics"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Heat"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Celtics"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Heat"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | [:serve "Tony Parker"->"Hornets"@0] | | | | | | [:serve "Tony Parker"->"Spurs"@0] | | | | | | [:like "Boris Diaw"->"Tony Parker"@0] | | | @@ -411,12 +411,12 @@ Feature: Integer Vid subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:serve "Danny Green"->"Spurs"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Manu Ginobili"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:serve "Boris Diaw"->"Spurs"@0] | @@ -449,12 +449,12 @@ Feature: Integer Vid subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:serve "Danny Green"->"Spurs"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Manu Ginobili"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:serve "Boris Diaw"->"Spurs"@0] | @@ -496,80 +496,80 @@ Feature: Integer Vid subgraph GET SUBGRAPH WITH PROP 4 steps from hash('Yao Ming') IN teammate OUT serve BOTH like """ Then define some list variables: - | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | - | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquile O'Neal") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | - | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | - | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | - | | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | - | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | - | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | - | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | - | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | - | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | - | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | - | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | - | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | - | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | - | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | - | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | - | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | - | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | - | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | - | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | - | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | - | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | - | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | - | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | - | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | - | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | - | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | - | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | - | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | - | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | - | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | - | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | - | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | - | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | - | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | - | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | - | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | - | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | - | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | - | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | - | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | + | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | + | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquille O'Neal") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | + | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | + | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | + | | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | + | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | + | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | + | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | + | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | + | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | + | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | + | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | + | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | + | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | + | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | + | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | + | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | + | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | + | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | + | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | + | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | + | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | + | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | + | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | + | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | + | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | + | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | + | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | + | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | + | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | + | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | + | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | + | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | + | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | + | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | + | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | + | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | + | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | + | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | + | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | + | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | Then the result should be, in any order, with relax comparison: | _vertices | _edges | | [("Yao Ming")] | <[edge1]> | @@ -587,21 +587,21 @@ Feature: Integer Vid subgraph | [:serve "Tony Parker"->"Spurs"@0] | ("Boris Diaw") | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Rudy Gay") | [:serve "Aron Baynes"->"Pistons"@0] | ("Ray Allen") | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Kristaps Porzingis") | [:serve "Grant Hill"->"Magic"@0] | ("Paul Gasol") | [:serve "Steve Nash"->"Mavericks"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("LaMarcus Aldridge") | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Damian Lillard") | [:serve "Aron Baynes"->"Spurs"@0] | ("Blake Griffin") | [:serve "Ray Allen"->"Bucks"@0] | ("Dirk Nowitzki") | [:serve "Grant Hill"->"Pistons"@0] | ("Jason Kidd") | [:serve "Steve Nash"->"Suns"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | ("Manu Ginobili") | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Kevin Durant") | [:serve "Rudy Gay"->"Grizzlies"@0] | ("Paul George") | [:serve "Ray Allen"->"Celtics"@0] | ("Rajon Rondo") | [:serve "Grant Hill"->"Suns"@0] | ("Pelicans") | [:serve "Steve Nash"->"Suns"@1] | - | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | + | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Dejounte Murray") | [:like "Danny Green"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Rudy Gay"->"Raptors"@0] | ("Luka Doncic") | [:serve "Ray Allen"->"Thunders"@0] | ("Kobe Bryant") | [:serve "Kristaps Porzingis"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Spurs"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | ("Hornets") | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Russell Westbrook") | [:serve "Rudy Gay"->"Spurs"@0] | ("Carmelo Anthony") | [:like "Rajon Rondo"->"Ray Allen"@0] | ("Wizards") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | | [:like "Steve Nash"->"Jason Kidd"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | ("Spurs") | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Danny Green") | [:like "Tracy McGrady"->"Rudy Gay"@0] | ("Tracy McGrady") | [:like "Ray Allen"->"Rajon Rondo"@0] | ("Pacers") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Kyle Anderson") | [:serve "Damian Lillard"->"Trail Blazers"@0] | ("Dwyane Wade") | [:serve "Blake Griffin"->"Clippers"@0] | ("Knicks") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | | [:serve "Jason Kidd"->"Knicks"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("James Harden") | [:serve "Kevin Durant"->"Thunders"@0] | ("Kyrie Irving") | [:serve "Blake Griffin"->"Pistons"@0] | ("Bucks") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "Jason Kidd"->"Mavericks"@0] | - | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | - | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | - | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | - | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | - | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | - | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquile O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | - | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | - | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | - | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | + | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | + | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | + | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | + | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | + | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | + | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquille O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | + | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | + | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | + | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | ("Raptors") | [:serve "Tiago Splitter"->"76ers"@0] | ("Rockets") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | [:serve "Vince Carter"->"Kings"@0] | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | ("76ers") | [:serve "Tiago Splitter"->"Hawks"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | [:serve "Vince Carter"->"Magic"@0] | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | [:serve "Tiago Splitter"->"Spurs"@0] | | [:serve "Carmelo Anthony"->"Knicks"@0] | | [:serve "Vince Carter"->"Mavericks"@0] | | | @@ -659,8 +659,8 @@ Feature: Integer Vid subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -673,8 +673,8 @@ Feature: Integer Vid subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | _vertices | _edges | | [("Tim Duncan")] | <[edge1]> | @@ -722,80 +722,80 @@ Feature: Integer Vid subgraph GET SUBGRAPH 4 steps from hash('Yao Ming') IN teammate OUT serve BOTH like """ Then define some list variables: - | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | - | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquile O'Neal") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | - | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | - | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | - | | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | - | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | - | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | - | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | - | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | - | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | - | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | - | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | - | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | - | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | - | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | - | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | - | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | - | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | - | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | - | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | - | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | - | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | - | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | - | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | - | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | - | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | - | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | - | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | - | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | - | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | - | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | - | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | - | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | - | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | - | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | - | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | - | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | - | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | - | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | - | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | - | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | + | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | + | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquille O'Neal") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | + | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | + | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | + | | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | + | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | + | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | + | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | + | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | + | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | + | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | + | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | + | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | + | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | + | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | + | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | + | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | + | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | + | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | + | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | + | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | + | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | + | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | + | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | + | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | + | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | + | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | + | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | + | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | + | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | + | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | + | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | + | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | + | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | + | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | + | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | + | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | + | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | + | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | + | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | + | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | Then the result should be, in any order, with relax comparison: | _vertices | _edges | | [("Yao Ming")] | <[edge1]> | @@ -813,21 +813,21 @@ Feature: Integer Vid subgraph | [:serve "Tony Parker"->"Spurs"@0] | ("Boris Diaw") | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Rudy Gay") | [:serve "Aron Baynes"->"Pistons"@0] | ("Ray Allen") | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Kristaps Porzingis") | [:serve "Grant Hill"->"Magic"@0] | ("Paul Gasol") | [:serve "Steve Nash"->"Mavericks"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("LaMarcus Aldridge") | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Damian Lillard") | [:serve "Aron Baynes"->"Spurs"@0] | ("Blake Griffin") | [:serve "Ray Allen"->"Bucks"@0] | ("Dirk Nowitzki") | [:serve "Grant Hill"->"Pistons"@0] | ("Jason Kidd") | [:serve "Steve Nash"->"Suns"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | ("Manu Ginobili") | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Kevin Durant") | [:serve "Rudy Gay"->"Grizzlies"@0] | ("Paul George") | [:serve "Ray Allen"->"Celtics"@0] | ("Rajon Rondo") | [:serve "Grant Hill"->"Suns"@0] | ("Pelicans") | [:serve "Steve Nash"->"Suns"@1] | - | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | + | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Dejounte Murray") | [:like "Danny Green"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Rudy Gay"->"Raptors"@0] | ("Luka Doncic") | [:serve "Ray Allen"->"Thunders"@0] | ("Kobe Bryant") | [:serve "Kristaps Porzingis"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Spurs"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | ("Hornets") | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Russell Westbrook") | [:serve "Rudy Gay"->"Spurs"@0] | ("Carmelo Anthony") | [:like "Rajon Rondo"->"Ray Allen"@0] | ("Wizards") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | | [:like "Steve Nash"->"Jason Kidd"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | ("Spurs") | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Danny Green") | [:like "Tracy McGrady"->"Rudy Gay"@0] | ("Tracy McGrady") | [:like "Ray Allen"->"Rajon Rondo"@0] | ("Pacers") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Kyle Anderson") | [:serve "Damian Lillard"->"Trail Blazers"@0] | ("Dwyane Wade") | [:serve "Blake Griffin"->"Clippers"@0] | ("Knicks") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | | [:serve "Jason Kidd"->"Knicks"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("James Harden") | [:serve "Kevin Durant"->"Thunders"@0] | ("Kyrie Irving") | [:serve "Blake Griffin"->"Pistons"@0] | ("Bucks") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "Jason Kidd"->"Mavericks"@0] | - | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | - | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | - | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | - | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | - | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | - | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquile O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | - | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | - | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | - | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | + | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | + | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | + | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | + | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | + | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | + | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquille O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | + | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | + | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | + | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | ("Raptors") | [:serve "Tiago Splitter"->"76ers"@0] | ("Rockets") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | [:serve "Vince Carter"->"Kings"@0] | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | ("76ers") | [:serve "Tiago Splitter"->"Hawks"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | [:serve "Vince Carter"->"Magic"@0] | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | [:serve "Tiago Splitter"->"Spurs"@0] | | [:serve "Carmelo Anthony"->"Knicks"@0] | | [:serve "Vince Carter"->"Mavericks"@0] | | | @@ -885,8 +885,8 @@ Feature: Integer Vid subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -899,8 +899,8 @@ Feature: Integer Vid subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | _vertices | _edges | | [("Tim Duncan")] | <[edge1]> | @@ -971,12 +971,12 @@ Feature: Integer Vid subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Tony Parker"->"Manu Ginobili"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:serve "Manu Ginobili"->"Spurs"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:serve "Manu Ginobili"->"Spurs"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Boris Diaw"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Dejounte Murray"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Dejounte Murray"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | @@ -1008,12 +1008,12 @@ Feature: Integer Vid subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | ("Pistons") | [:serve "LeBron James"->"Cavaliers"@1] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"LeBron James"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Danny Green"->"Marco Belinelli"@0] | ("Kings") | [:serve "Rudy Gay"->"Kings"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | ("Raptors") | [:serve "Cory Joseph"->"Raptors"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | ("Raptors") | [:serve "Cory Joseph"->"Raptors"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:serve "Danny Green"->"Raptors"@0] | ("Jazz") | [:serve "Rudy Gay"->"Raptors"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:serve "Danny Green"->"Spurs"@0] | ("LeBron James") | [:serve "Tracy McGrady"->"Raptors"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Paul Gasol") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("Kyle Anderson") | [:serve "LeBron James"->"Heat"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Rudy Gay") | [:serve "LeBron James"->"Lakers"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Rudy Gay") | [:serve "LeBron James"->"Lakers"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Paul Gasol"->"Bulls"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:serve "Manu Ginobili"->"Spurs"@0] | ("Yao Ming") | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("James Harden") | [:like "Tracy McGrady"->"Rudy Gay"@0] | @@ -1026,14 +1026,14 @@ Feature: Integer Vid subgraph | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Heat") | [:serve "David West"->"Warriors"@0] | | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Lakers") | [:serve "Jonathon Simmons"->"76ers"@0] | | | | [:serve "Boris Diaw"->"Suns"@0] | ("Suns") | [:serve "Jonathon Simmons"->"Magic"@0] | - | | | [:like "Yao Ming"->"Shaquile O\'Neal"@0] | ("Magic") | [:serve "JaVale McGee"->"Lakers"@0] | - | | | [:like "Shaquile O\'Neal"->"JaVale McGee"@0] | ("Trail Blazers") | [:serve "Tracy McGrady"->"Magic"@0] | - | | | [:serve "Shaquile O\'Neal"->"Cavaliers"@0] | ("76ers") | [:serve "JaVale McGee"->"Warriors"@0] | - | | | [:serve "Shaquile O\'Neal"->"Celtics"@0] | ("JaVale McGee") | | - | | | [:serve "Shaquile O\'Neal"->"Heat"@0] | ("Cory Joseph") | | - | | | [:serve "Shaquile O\'Neal"->"Lakers"@0] | ("Tracy McGrady") | | - | | | [:serve "Shaquile O\'Neal"->"Magic"@0] | ("Russell Westbrook") | | - | | | [:serve "Shaquile O\'Neal"->"Suns"@0] | ("Bulls") | | + | | | [:like "Yao Ming"->"Shaquille O\'Neal"@0] | ("Magic") | [:serve "JaVale McGee"->"Lakers"@0] | + | | | [:like "Shaquille O\'Neal"->"JaVale McGee"@0] | ("Trail Blazers") | [:serve "Tracy McGrady"->"Magic"@0] | + | | | [:serve "Shaquille O\'Neal"->"Cavaliers"@0] | ("76ers") | [:serve "JaVale McGee"->"Warriors"@0] | + | | | [:serve "Shaquille O\'Neal"->"Celtics"@0] | ("JaVale McGee") | | + | | | [:serve "Shaquille O\'Neal"->"Heat"@0] | ("Cory Joseph") | | + | | | [:serve "Shaquille O\'Neal"->"Lakers"@0] | ("Tracy McGrady") | | + | | | [:serve "Shaquille O\'Neal"->"Magic"@0] | ("Russell Westbrook") | | + | | | [:serve "Shaquille O\'Neal"->"Suns"@0] | ("Bulls") | | | | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Warriors") | | | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | @@ -1091,14 +1091,14 @@ Feature: Integer Vid subgraph | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Danny Green") | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | ("Yao Ming") | | [:like "Danny Green"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | ("Rudy Gay") | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | | - | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Marco Belinelli"->"Danny Green"@0] | | + | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Marco Belinelli"->"Danny Green"@0] | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Danny Green"->"Marco Belinelli"@0] | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Tim Duncan"->"Manu Ginobili"@0] | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | [:like "Boris Diaw"->"Tony Parker"@0] | | | | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | @@ -1125,7 +1125,7 @@ Feature: Integer Vid subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Aron Baynes") | [:serve "Danny Green"->"Cavaliers"@0] | ("Bulls") | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Manu Ginobili") | [:serve "Danny Green"->"Raptors"@0] | ("Trail Blazers") | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Danny Green"->"Spurs"@0] | ("Celtics") | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Danny Green"@0] | ("Kings") | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Danny Green"@0] | ("Kings") | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Marco Belinelli"->"Danny Green"@0] | ("Hawks") | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Spurs") | [:serve "Marco Belinelli"->"76ers"@0] | ("Warriors") | | | | | [:serve "Marco Belinelli"->"Bulls"@0] | ("Cavaliers") | | @@ -1156,13 +1156,13 @@ Feature: Integer Vid subgraph | | | [:serve "Tiago Splitter"->"76ers"@0] | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Celtics"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Heat"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Celtics"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Heat"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | [:serve "Tony Parker"->"Hornets"@0] | | | | | | [:serve "Tony Parker"->"Spurs"@0] | | | | | | [:like "Boris Diaw"->"Tony Parker"@0] | | | @@ -1262,12 +1262,12 @@ Feature: Integer Vid subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:serve "Danny Green"->"Spurs"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Manu Ginobili"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:serve "Boris Diaw"->"Spurs"@0] | @@ -1300,12 +1300,12 @@ Feature: Integer Vid subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:serve "Danny Green"->"Spurs"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Manu Ginobili"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:serve "Boris Diaw"->"Spurs"@0] | @@ -1347,80 +1347,80 @@ Feature: Integer Vid subgraph GET SUBGRAPH WITH PROP 4 steps from hash('Yao Ming') IN teammate OUT serve BOTH like YIELD VERTiCeS as nodes , EDgES as relationships """ Then define some list variables: - | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | - | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquile O'Neal") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | - | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | - | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | - | | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | - | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | - | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | - | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | - | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | - | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | - | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | - | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | - | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | - | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | - | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | - | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | - | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | - | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | - | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | - | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | - | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | - | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | - | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | - | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | - | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | - | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | - | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | - | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | - | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | - | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | - | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | - | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | - | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | - | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | - | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | - | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | - | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | - | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | - | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | - | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | - | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | + | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | + | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquille O'Neal") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | + | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | + | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | + | | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | + | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | + | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | + | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | + | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | + | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | + | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | + | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | + | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | + | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | + | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | + | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | + | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | + | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | + | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | + | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | + | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | + | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | + | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | + | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | + | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | + | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | + | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | + | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | + | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | + | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | + | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | + | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | + | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | + | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | + | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | + | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | + | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | + | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | + | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | + | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | + | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Yao Ming")] | <[edge1]> | @@ -1438,21 +1438,21 @@ Feature: Integer Vid subgraph | [:serve "Tony Parker"->"Spurs"@0] | ("Boris Diaw") | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Rudy Gay") | [:serve "Aron Baynes"->"Pistons"@0] | ("Ray Allen") | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Kristaps Porzingis") | [:serve "Grant Hill"->"Magic"@0] | ("Paul Gasol") | [:serve "Steve Nash"->"Mavericks"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("LaMarcus Aldridge") | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Damian Lillard") | [:serve "Aron Baynes"->"Spurs"@0] | ("Blake Griffin") | [:serve "Ray Allen"->"Bucks"@0] | ("Dirk Nowitzki") | [:serve "Grant Hill"->"Pistons"@0] | ("Jason Kidd") | [:serve "Steve Nash"->"Suns"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | ("Manu Ginobili") | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Kevin Durant") | [:serve "Rudy Gay"->"Grizzlies"@0] | ("Paul George") | [:serve "Ray Allen"->"Celtics"@0] | ("Rajon Rondo") | [:serve "Grant Hill"->"Suns"@0] | ("Pelicans") | [:serve "Steve Nash"->"Suns"@1] | - | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | + | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Dejounte Murray") | [:like "Danny Green"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Rudy Gay"->"Raptors"@0] | ("Luka Doncic") | [:serve "Ray Allen"->"Thunders"@0] | ("Kobe Bryant") | [:serve "Kristaps Porzingis"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Spurs"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | ("Hornets") | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Russell Westbrook") | [:serve "Rudy Gay"->"Spurs"@0] | ("Carmelo Anthony") | [:like "Rajon Rondo"->"Ray Allen"@0] | ("Wizards") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | | [:like "Steve Nash"->"Jason Kidd"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | ("Spurs") | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Danny Green") | [:like "Tracy McGrady"->"Rudy Gay"@0] | ("Tracy McGrady") | [:like "Ray Allen"->"Rajon Rondo"@0] | ("Pacers") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Kyle Anderson") | [:serve "Damian Lillard"->"Trail Blazers"@0] | ("Dwyane Wade") | [:serve "Blake Griffin"->"Clippers"@0] | ("Knicks") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | | [:serve "Jason Kidd"->"Knicks"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("James Harden") | [:serve "Kevin Durant"->"Thunders"@0] | ("Kyrie Irving") | [:serve "Blake Griffin"->"Pistons"@0] | ("Bucks") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "Jason Kidd"->"Mavericks"@0] | - | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | - | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | - | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | - | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | - | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | - | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquile O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | - | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | - | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | - | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | + | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | + | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | + | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | + | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | + | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | + | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquille O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | + | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | + | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | + | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | ("Raptors") | [:serve "Tiago Splitter"->"76ers"@0] | ("Rockets") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | [:serve "Vince Carter"->"Kings"@0] | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | ("76ers") | [:serve "Tiago Splitter"->"Hawks"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | [:serve "Vince Carter"->"Magic"@0] | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | [:serve "Tiago Splitter"->"Spurs"@0] | | [:serve "Carmelo Anthony"->"Knicks"@0] | | [:serve "Vince Carter"->"Mavericks"@0] | | | @@ -1510,8 +1510,8 @@ Feature: Integer Vid subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -1524,8 +1524,8 @@ Feature: Integer Vid subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Tim Duncan")] | <[edge1]> | @@ -1573,80 +1573,80 @@ Feature: Integer Vid subgraph GET SUBGRAPH 4 steps from hash('Yao Ming') IN teammate OUT serve BOTH like YIELD VERTICES as nodes, EDGES as relationships """ Then define some list variables: - | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | - | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquile O'Neal") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | - | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | - | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | - | | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | - | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | - | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | - | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | - | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | - | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | - | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | - | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | - | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | - | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | - | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | - | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | - | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | - | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | - | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | - | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | - | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | - | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | - | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | - | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | - | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | - | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | - | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | - | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | - | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | - | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | - | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | - | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | - | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | - | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | - | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | - | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | - | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | - | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | - | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | - | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | - | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | + | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | + | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquille O'Neal") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | + | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | + | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | + | | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | + | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | + | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | + | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | + | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | + | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | + | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | + | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | + | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | + | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | + | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | + | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | + | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | + | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | + | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | + | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | + | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | + | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | + | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | + | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | + | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | + | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | + | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | + | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | + | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | + | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | + | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | + | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | + | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | + | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | + | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | + | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | + | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | + | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | + | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | + | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | + | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Yao Ming")] | <[edge1]> | @@ -1664,21 +1664,21 @@ Feature: Integer Vid subgraph | [:serve "Tony Parker"->"Spurs"@0] | ("Boris Diaw") | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Rudy Gay") | [:serve "Aron Baynes"->"Pistons"@0] | ("Ray Allen") | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Kristaps Porzingis") | [:serve "Grant Hill"->"Magic"@0] | ("Paul Gasol") | [:serve "Steve Nash"->"Mavericks"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("LaMarcus Aldridge") | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Damian Lillard") | [:serve "Aron Baynes"->"Spurs"@0] | ("Blake Griffin") | [:serve "Ray Allen"->"Bucks"@0] | ("Dirk Nowitzki") | [:serve "Grant Hill"->"Pistons"@0] | ("Jason Kidd") | [:serve "Steve Nash"->"Suns"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | ("Manu Ginobili") | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Kevin Durant") | [:serve "Rudy Gay"->"Grizzlies"@0] | ("Paul George") | [:serve "Ray Allen"->"Celtics"@0] | ("Rajon Rondo") | [:serve "Grant Hill"->"Suns"@0] | ("Pelicans") | [:serve "Steve Nash"->"Suns"@1] | - | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | + | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Dejounte Murray") | [:like "Danny Green"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Rudy Gay"->"Raptors"@0] | ("Luka Doncic") | [:serve "Ray Allen"->"Thunders"@0] | ("Kobe Bryant") | [:serve "Kristaps Porzingis"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Spurs"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | ("Hornets") | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Russell Westbrook") | [:serve "Rudy Gay"->"Spurs"@0] | ("Carmelo Anthony") | [:like "Rajon Rondo"->"Ray Allen"@0] | ("Wizards") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | | [:like "Steve Nash"->"Jason Kidd"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | ("Spurs") | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Danny Green") | [:like "Tracy McGrady"->"Rudy Gay"@0] | ("Tracy McGrady") | [:like "Ray Allen"->"Rajon Rondo"@0] | ("Pacers") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Kyle Anderson") | [:serve "Damian Lillard"->"Trail Blazers"@0] | ("Dwyane Wade") | [:serve "Blake Griffin"->"Clippers"@0] | ("Knicks") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | | [:serve "Jason Kidd"->"Knicks"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("James Harden") | [:serve "Kevin Durant"->"Thunders"@0] | ("Kyrie Irving") | [:serve "Blake Griffin"->"Pistons"@0] | ("Bucks") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "Jason Kidd"->"Mavericks"@0] | - | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | - | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | - | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | - | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | - | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | - | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquile O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | - | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | - | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | - | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | + | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | + | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | + | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | + | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | + | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | + | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquille O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | + | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | + | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | + | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | ("Raptors") | [:serve "Tiago Splitter"->"76ers"@0] | ("Rockets") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | [:serve "Vince Carter"->"Kings"@0] | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | ("76ers") | [:serve "Tiago Splitter"->"Hawks"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | [:serve "Vince Carter"->"Magic"@0] | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | [:serve "Tiago Splitter"->"Spurs"@0] | | [:serve "Carmelo Anthony"->"Knicks"@0] | | [:serve "Vince Carter"->"Mavericks"@0] | | | @@ -1736,8 +1736,8 @@ Feature: Integer Vid subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -1750,8 +1750,8 @@ Feature: Integer Vid subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Tim Duncan")] | <[edge1]> | @@ -1792,11 +1792,11 @@ Feature: Integer Vid subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | [:like "Dejounte Murray"->"Marco Belinelli"@0] | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | [:like "Dejounte Murray"->"Manu Ginobili"@0] | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | [:like "Tim Duncan"->"Manu Ginobili"@0] | | | [:like "Tony Parker"->"Manu Ginobili"@0] | - | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | + | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | [:like "Boris Diaw"->"Tony Parker"@0] | | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | @@ -1838,8 +1838,8 @@ Feature: Integer Vid subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -1852,8 +1852,8 @@ Feature: Integer Vid subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Tim Duncan")] | <[edge1]> | diff --git a/tests/tck/features/subgraph/subgraph.feature b/tests/tck/features/subgraph/subgraph.feature index 24250f98b9d..622b28b8fae 100644 --- a/tests/tck/features/subgraph/subgraph.feature +++ b/tests/tck/features/subgraph/subgraph.feature @@ -19,7 +19,7 @@ Feature: subgraph Then a SemanticError should be raised at runtime: `$a.id', not exist variable `a' When executing query: """ - GET SUBGRAPH WITH PROP FROM "Tim Duncan" YIELD vertexs + GET SUBGRAPH WITH PROP FROM "Tim Duncan" YIELD invalidColumn """ Then a SemanticError should be raised at runtime: Get Subgraph only support YIELD vertices OR edges When executing query: @@ -120,12 +120,12 @@ Feature: subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Tony Parker"->"Manu Ginobili"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:serve "Manu Ginobili"->"Spurs"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:serve "Manu Ginobili"->"Spurs"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Boris Diaw"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Dejounte Murray"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Dejounte Murray"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | @@ -157,12 +157,12 @@ Feature: subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | ("Pistons") | [:serve "LeBron James"->"Cavaliers"@1] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"LeBron James"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Danny Green"->"Marco Belinelli"@0] | ("Kings") | [:serve "Rudy Gay"->"Kings"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | ("Raptors") | [:serve "Cory Joseph"->"Raptors"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:serve "Danny Green"->"Cavaliers"@0] | ("Raptors") | [:serve "Cory Joseph"->"Raptors"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:serve "Danny Green"->"Raptors"@0] | ("Jazz") | [:serve "Rudy Gay"->"Raptors"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:serve "Danny Green"->"Spurs"@0] | ("LeBron James") | [:serve "Tracy McGrady"->"Raptors"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Paul Gasol") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("Kyle Anderson") | [:serve "LeBron James"->"Heat"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Rudy Gay") | [:serve "LeBron James"->"Lakers"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Rudy Gay") | [:serve "LeBron James"->"Lakers"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Paul Gasol"->"Bulls"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:serve "Manu Ginobili"->"Spurs"@0] | ("Yao Ming") | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("James Harden") | [:like "Tracy McGrady"->"Rudy Gay"@0] | @@ -175,14 +175,14 @@ Feature: subgraph | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Heat") | [:serve "David West"->"Warriors"@0] | | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Lakers") | [:serve "Jonathon Simmons"->"76ers"@0] | | | | [:serve "Boris Diaw"->"Suns"@0] | ("Suns") | [:serve "Jonathon Simmons"->"Magic"@0] | - | | | [:like "Yao Ming"->"Shaquile O\'Neal"@0] | ("Magic") | [:serve "JaVale McGee"->"Lakers"@0] | - | | | [:like "Shaquile O\'Neal"->"JaVale McGee"@0] | ("Trail Blazers") | [:serve "Tracy McGrady"->"Magic"@0] | - | | | [:serve "Shaquile O\'Neal"->"Cavaliers"@0] | ("76ers") | [:serve "JaVale McGee"->"Warriors"@0] | - | | | [:serve "Shaquile O\'Neal"->"Celtics"@0] | ("JaVale McGee") | | - | | | [:serve "Shaquile O\'Neal"->"Heat"@0] | ("Cory Joseph") | | - | | | [:serve "Shaquile O\'Neal"->"Lakers"@0] | ("Tracy McGrady") | | - | | | [:serve "Shaquile O\'Neal"->"Magic"@0] | ("Russell Westbrook") | | - | | | [:serve "Shaquile O\'Neal"->"Suns"@0] | ("Bulls") | | + | | | [:like "Yao Ming"->"Shaquille O\'Neal"@0] | ("Magic") | [:serve "JaVale McGee"->"Lakers"@0] | + | | | [:like "Shaquille O\'Neal"->"JaVale McGee"@0] | ("Trail Blazers") | [:serve "Tracy McGrady"->"Magic"@0] | + | | | [:serve "Shaquille O\'Neal"->"Cavaliers"@0] | ("76ers") | [:serve "JaVale McGee"->"Warriors"@0] | + | | | [:serve "Shaquille O\'Neal"->"Celtics"@0] | ("JaVale McGee") | | + | | | [:serve "Shaquille O\'Neal"->"Heat"@0] | ("Cory Joseph") | | + | | | [:serve "Shaquille O\'Neal"->"Lakers"@0] | ("Tracy McGrady") | | + | | | [:serve "Shaquille O\'Neal"->"Magic"@0] | ("Russell Westbrook") | | + | | | [:serve "Shaquille O\'Neal"->"Suns"@0] | ("Bulls") | | | | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Warriors") | | | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | @@ -240,14 +240,14 @@ Feature: subgraph | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Danny Green") | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | ("Yao Ming") | | [:like "Danny Green"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | ("Rudy Gay") | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | | - | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Marco Belinelli"->"Danny Green"@0] | | + | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Marco Belinelli"->"Danny Green"@0] | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Danny Green"->"Marco Belinelli"@0] | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Boris Diaw") | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Tim Duncan"->"Manu Ginobili"@0] | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | [:like "Boris Diaw"->"Tony Parker"@0] | | | | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | @@ -274,7 +274,7 @@ Feature: subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Aron Baynes") | [:serve "Danny Green"->"Cavaliers"@0] | ("Bulls") | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Manu Ginobili") | [:serve "Danny Green"->"Raptors"@0] | ("Trail Blazers") | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Danny Green"->"Spurs"@0] | ("Celtics") | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Danny Green"@0] | ("Kings") | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Danny Green"@0] | ("Kings") | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Marco Belinelli"->"Danny Green"@0] | ("Hawks") | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Spurs") | [:serve "Marco Belinelli"->"76ers"@0] | ("Warriors") | | | | | [:serve "Marco Belinelli"->"Bulls"@0] | ("Cavaliers") | | @@ -305,13 +305,13 @@ Feature: subgraph | | | [:serve "Tiago Splitter"->"76ers"@0] | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Celtics"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Heat"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | | | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Celtics"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Heat"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | | | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | [:serve "Tony Parker"->"Hornets"@0] | | | | | | [:serve "Tony Parker"->"Spurs"@0] | | | | | | [:like "Boris Diaw"->"Tony Parker"@0] | | | @@ -411,12 +411,12 @@ Feature: subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:serve "Danny Green"->"Spurs"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Manu Ginobili"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:serve "Boris Diaw"->"Spurs"@0] | @@ -449,12 +449,12 @@ Feature: subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:serve "Danny Green"->"Spurs"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Manu Ginobili"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:serve "Boris Diaw"->"Spurs"@0] | @@ -496,80 +496,80 @@ Feature: subgraph GET SUBGRAPH WITH PROP 4 steps from 'Yao Ming' IN teammate OUT serve BOTH like YIELD VERTICES as nodes, EDGES as relationships """ Then define some list variables: - | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | - | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquile O'Neal") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | - | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | - | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | - | | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | - | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | - | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | - | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | - | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | - | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | - | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | - | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | - | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | - | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | - | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | - | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | - | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | - | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | - | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | - | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | - | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | - | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | - | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | - | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | - | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | - | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | - | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | - | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | - | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | - | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | - | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | - | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | - | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | - | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | - | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | - | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | - | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | - | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | - | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | - | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | - | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | + | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | + | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquille O'Neal") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | + | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | + | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | + | | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | + | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | + | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | + | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | + | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | + | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | + | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | + | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | + | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | + | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | + | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | + | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | + | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | + | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | + | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | + | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | + | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | + | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | + | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | + | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | + | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | + | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | + | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | + | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | + | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | + | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | + | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | + | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | + | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | + | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | + | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | + | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | + | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | + | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | + | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | + | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | + | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Yao Ming")] | <[edge1]> | @@ -587,21 +587,21 @@ Feature: subgraph | [:serve "Tony Parker"->"Spurs"@0] | ("Boris Diaw") | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Rudy Gay") | [:serve "Aron Baynes"->"Pistons"@0] | ("Ray Allen") | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Kristaps Porzingis") | [:serve "Grant Hill"->"Magic"@0] | ("Paul Gasol") | [:serve "Steve Nash"->"Mavericks"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("LaMarcus Aldridge") | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Damian Lillard") | [:serve "Aron Baynes"->"Spurs"@0] | ("Blake Griffin") | [:serve "Ray Allen"->"Bucks"@0] | ("Dirk Nowitzki") | [:serve "Grant Hill"->"Pistons"@0] | ("Jason Kidd") | [:serve "Steve Nash"->"Suns"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | ("Manu Ginobili") | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Kevin Durant") | [:serve "Rudy Gay"->"Grizzlies"@0] | ("Paul George") | [:serve "Ray Allen"->"Celtics"@0] | ("Rajon Rondo") | [:serve "Grant Hill"->"Suns"@0] | ("Pelicans") | [:serve "Steve Nash"->"Suns"@1] | - | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | + | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Dejounte Murray") | [:like "Danny Green"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Rudy Gay"->"Raptors"@0] | ("Luka Doncic") | [:serve "Ray Allen"->"Thunders"@0] | ("Kobe Bryant") | [:serve "Kristaps Porzingis"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Spurs"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | ("Hornets") | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Russell Westbrook") | [:serve "Rudy Gay"->"Spurs"@0] | ("Carmelo Anthony") | [:like "Rajon Rondo"->"Ray Allen"@0] | ("Wizards") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | | [:like "Steve Nash"->"Jason Kidd"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | ("Spurs") | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Danny Green") | [:like "Tracy McGrady"->"Rudy Gay"@0] | ("Tracy McGrady") | [:like "Ray Allen"->"Rajon Rondo"@0] | ("Pacers") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Kyle Anderson") | [:serve "Damian Lillard"->"Trail Blazers"@0] | ("Dwyane Wade") | [:serve "Blake Griffin"->"Clippers"@0] | ("Knicks") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | | [:serve "Jason Kidd"->"Knicks"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("James Harden") | [:serve "Kevin Durant"->"Thunders"@0] | ("Kyrie Irving") | [:serve "Blake Griffin"->"Pistons"@0] | ("Bucks") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "Jason Kidd"->"Mavericks"@0] | - | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | - | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | - | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | - | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | - | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | - | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquile O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | - | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | - | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | - | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | + | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | + | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | + | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | + | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | + | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | + | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquille O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | + | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | + | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | + | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | ("Raptors") | [:serve "Tiago Splitter"->"76ers"@0] | ("Rockets") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | [:serve "Vince Carter"->"Kings"@0] | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | ("76ers") | [:serve "Tiago Splitter"->"Hawks"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | [:serve "Vince Carter"->"Magic"@0] | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | [:serve "Tiago Splitter"->"Spurs"@0] | | [:serve "Carmelo Anthony"->"Knicks"@0] | | [:serve "Vince Carter"->"Mavericks"@0] | | | @@ -659,8 +659,8 @@ Feature: subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -673,8 +673,8 @@ Feature: subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Tim Duncan")] | <[edge1]> | @@ -722,80 +722,80 @@ Feature: subgraph GET SUBGRAPH 4 steps from 'Yao Ming' IN teammate OUT serve BOTH like YIELD vertices as nodes, edges as relationships """ Then define some list variables: - | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | - | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquile O'Neal") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | - | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | - | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | - | | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | - | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | - | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | - | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | - | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | - | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | - | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | - | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | - | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | - | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | - | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | - | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | - | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | - | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | - | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | - | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | - | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | - | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | - | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | - | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | - | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | - | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | - | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | - | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | - | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | - | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | - | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | - | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | - | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | - | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | - | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | - | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | - | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | - | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | - | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | - | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | - | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | + | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | + | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquille O'Neal") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | + | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | + | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | + | | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | + | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | + | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | + | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | + | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | + | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | + | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | + | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | + | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | + | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | + | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | + | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | + | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | + | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | + | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | + | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | + | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | + | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | + | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | + | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | + | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | + | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | + | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | + | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | + | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | + | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | + | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | + | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | + | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | + | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | + | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | + | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | + | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | + | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | + | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | + | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | + | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Yao Ming")] | <[edge1]> | @@ -813,21 +813,21 @@ Feature: subgraph | [:serve "Tony Parker"->"Spurs"@0] | ("Boris Diaw") | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Rudy Gay") | [:serve "Aron Baynes"->"Pistons"@0] | ("Ray Allen") | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Kristaps Porzingis") | [:serve "Grant Hill"->"Magic"@0] | ("Paul Gasol") | [:serve "Steve Nash"->"Mavericks"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("LaMarcus Aldridge") | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Damian Lillard") | [:serve "Aron Baynes"->"Spurs"@0] | ("Blake Griffin") | [:serve "Ray Allen"->"Bucks"@0] | ("Dirk Nowitzki") | [:serve "Grant Hill"->"Pistons"@0] | ("Jason Kidd") | [:serve "Steve Nash"->"Suns"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | ("Manu Ginobili") | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Kevin Durant") | [:serve "Rudy Gay"->"Grizzlies"@0] | ("Paul George") | [:serve "Ray Allen"->"Celtics"@0] | ("Rajon Rondo") | [:serve "Grant Hill"->"Suns"@0] | ("Pelicans") | [:serve "Steve Nash"->"Suns"@1] | - | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | + | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Dejounte Murray") | [:like "Danny Green"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Rudy Gay"->"Raptors"@0] | ("Luka Doncic") | [:serve "Ray Allen"->"Thunders"@0] | ("Kobe Bryant") | [:serve "Kristaps Porzingis"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Spurs"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | ("Hornets") | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Russell Westbrook") | [:serve "Rudy Gay"->"Spurs"@0] | ("Carmelo Anthony") | [:like "Rajon Rondo"->"Ray Allen"@0] | ("Wizards") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | | [:like "Steve Nash"->"Jason Kidd"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | ("Spurs") | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Danny Green") | [:like "Tracy McGrady"->"Rudy Gay"@0] | ("Tracy McGrady") | [:like "Ray Allen"->"Rajon Rondo"@0] | ("Pacers") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Kyle Anderson") | [:serve "Damian Lillard"->"Trail Blazers"@0] | ("Dwyane Wade") | [:serve "Blake Griffin"->"Clippers"@0] | ("Knicks") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | | [:serve "Jason Kidd"->"Knicks"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("James Harden") | [:serve "Kevin Durant"->"Thunders"@0] | ("Kyrie Irving") | [:serve "Blake Griffin"->"Pistons"@0] | ("Bucks") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "Jason Kidd"->"Mavericks"@0] | - | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | - | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | - | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | - | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | - | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | - | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquile O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | - | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | - | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | - | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | + | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | + | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | + | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | + | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | + | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | + | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquille O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | + | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | + | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | + | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | ("Raptors") | [:serve "Tiago Splitter"->"76ers"@0] | ("Rockets") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | [:serve "Vince Carter"->"Kings"@0] | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | ("76ers") | [:serve "Tiago Splitter"->"Hawks"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | [:serve "Vince Carter"->"Magic"@0] | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | [:serve "Tiago Splitter"->"Spurs"@0] | | [:serve "Carmelo Anthony"->"Knicks"@0] | | [:serve "Vince Carter"->"Mavericks"@0] | | | @@ -885,8 +885,8 @@ Feature: subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -899,8 +899,8 @@ Feature: subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | nodes | relationships | | [("Tim Duncan")] | <[edge1]> | @@ -941,11 +941,11 @@ Feature: subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | [:like "Dejounte Murray"->"Marco Belinelli"@0] | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | [:like "Dejounte Murray"->"Manu Ginobili"@0] | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | [:like "Tim Duncan"->"Manu Ginobili"@0] | | | [:like "Tony Parker"->"Manu Ginobili"@0] | - | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | + | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | [:like "Boris Diaw"->"Tony Parker"@0] | | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | @@ -987,8 +987,8 @@ Feature: subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -1001,8 +1001,8 @@ Feature: subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | a | b | | [("Tim Duncan")] | <[edge1]> | @@ -1066,12 +1066,12 @@ Feature: subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:serve "Danny Green"->"Spurs"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Manu Ginobili"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:serve "Boris Diaw"->"Spurs"@0] | @@ -1104,12 +1104,12 @@ Feature: subgraph | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Marco Belinelli"->"Danny Green"@0] | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Danny Green"->"Marco Belinelli"@0] | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Boris Diaw") | [:serve "Danny Green"->"Spurs"@0] | - | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquile O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | + | [:like "Danny Green"->"Tim Duncan"@0] | ("Shaquille O\'Neal") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Spurs") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("LaMarcus Aldridge") | [:serve "Manu Ginobili"->"Spurs"@0] | - | [:like "Shaquile O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | + | [:like "Shaquille O\'Neal"->"Tim Duncan"@0] | ("Marco Belinelli") | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Aron Baynes"->"Spurs"@0] | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:serve "Boris Diaw"->"Spurs"@0] | @@ -1151,80 +1151,80 @@ Feature: subgraph GET SUBGRAPH WITH PROP 4 steps from 'Yao Ming' IN teammate OUT serve BOTH like """ Then define some list variables: - | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | - | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquile O'Neal") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | - | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | - | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | - | | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | - | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | - | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | - | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | - | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | - | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | - | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | - | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | - | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | - | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | - | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | - | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | - | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | - | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | - | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | - | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | - | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | - | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | - | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | - | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | - | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | - | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | - | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | - | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | - | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | - | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | - | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | - | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | - | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | - | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | - | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | - | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | - | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | - | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | - | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | - | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | - | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | + | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | + | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquille O'Neal") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | + | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | + | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | + | | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | + | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | + | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | + | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | + | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | + | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | + | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | + | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | + | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | + | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | + | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | + | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | + | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | + | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | + | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | + | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | + | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | + | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | + | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | + | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | + | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | + | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | + | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | + | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | + | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | + | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | + | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | + | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | + | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | + | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | + | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | + | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | + | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | + | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | + | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | + | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | + | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | Then the result should be, in any order, with relax comparison: | _vertices | _edges | | [("Yao Ming")] | <[edge1]> | @@ -1242,21 +1242,21 @@ Feature: subgraph | [:serve "Tony Parker"->"Spurs"@0] | ("Boris Diaw") | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Rudy Gay") | [:serve "Aron Baynes"->"Pistons"@0] | ("Ray Allen") | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Kristaps Porzingis") | [:serve "Grant Hill"->"Magic"@0] | ("Paul Gasol") | [:serve "Steve Nash"->"Mavericks"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("LaMarcus Aldridge") | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Damian Lillard") | [:serve "Aron Baynes"->"Spurs"@0] | ("Blake Griffin") | [:serve "Ray Allen"->"Bucks"@0] | ("Dirk Nowitzki") | [:serve "Grant Hill"->"Pistons"@0] | ("Jason Kidd") | [:serve "Steve Nash"->"Suns"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | ("Manu Ginobili") | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Kevin Durant") | [:serve "Rudy Gay"->"Grizzlies"@0] | ("Paul George") | [:serve "Ray Allen"->"Celtics"@0] | ("Rajon Rondo") | [:serve "Grant Hill"->"Suns"@0] | ("Pelicans") | [:serve "Steve Nash"->"Suns"@1] | - | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | + | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Dejounte Murray") | [:like "Danny Green"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Rudy Gay"->"Raptors"@0] | ("Luka Doncic") | [:serve "Ray Allen"->"Thunders"@0] | ("Kobe Bryant") | [:serve "Kristaps Porzingis"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Spurs"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | ("Hornets") | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Russell Westbrook") | [:serve "Rudy Gay"->"Spurs"@0] | ("Carmelo Anthony") | [:like "Rajon Rondo"->"Ray Allen"@0] | ("Wizards") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | | [:like "Steve Nash"->"Jason Kidd"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | ("Spurs") | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Danny Green") | [:like "Tracy McGrady"->"Rudy Gay"@0] | ("Tracy McGrady") | [:like "Ray Allen"->"Rajon Rondo"@0] | ("Pacers") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Kyle Anderson") | [:serve "Damian Lillard"->"Trail Blazers"@0] | ("Dwyane Wade") | [:serve "Blake Griffin"->"Clippers"@0] | ("Knicks") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | | [:serve "Jason Kidd"->"Knicks"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("James Harden") | [:serve "Kevin Durant"->"Thunders"@0] | ("Kyrie Irving") | [:serve "Blake Griffin"->"Pistons"@0] | ("Bucks") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "Jason Kidd"->"Mavericks"@0] | - | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | - | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | - | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | - | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | - | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | - | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquile O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | - | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | - | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | - | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | + | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | + | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | + | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | + | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | + | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | + | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquille O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | + | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | + | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | + | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | ("Raptors") | [:serve "Tiago Splitter"->"76ers"@0] | ("Rockets") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | [:serve "Vince Carter"->"Kings"@0] | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | ("76ers") | [:serve "Tiago Splitter"->"Hawks"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | [:serve "Vince Carter"->"Magic"@0] | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | [:serve "Tiago Splitter"->"Spurs"@0] | | [:serve "Carmelo Anthony"->"Knicks"@0] | | [:serve "Vince Carter"->"Mavericks"@0] | | | @@ -1314,8 +1314,8 @@ Feature: subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -1328,8 +1328,8 @@ Feature: subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | _vertices | _edges | | [("Tim Duncan")] | <[edge1]> | @@ -1377,80 +1377,80 @@ Feature: subgraph GET SUBGRAPH 4 steps from 'Yao Ming' IN teammate OUT serve BOTH like """ Then define some list variables: - | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | - | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquile O'Neal") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | - | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | - | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | - | | | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | - | | | [:serve "Shaquile O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | - | | | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | - | | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | - | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | - | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | - | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | - | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | - | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | - | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | - | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | - | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | - | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | - | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | - | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | - | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | - | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | - | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | - | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | - | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | - | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | - | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | - | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | - | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | - | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | - | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | - | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | - | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | - | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | - | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | - | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | - | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | - | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | - | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | - | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | - | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | - | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | - | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | - | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | - | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | - | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | - | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | - | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | - | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | - | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | - | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | - | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | - | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | + | edge1 | vertex2 | edge2 | vertex3 | edge3 | vertex4 | edge4 | vertex5 | edge5 | + | [:serve "Yao Ming"->"Rockets"@0] | ("Shaquille O'Neal") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Kobe Bryant") | [:serve "Kobe Bryant"->"Lakers"@0] | ("Manu Ginobili") | [:serve "Manu Ginobili"->"Spurs"@0] | ("Dirk Nowitzki") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | + | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Tracy McGrady") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Grant Hill") | [:like "Paul Gasol"->"Kobe Bryant"@0] | ("Paul Gasol") | [:teammate "Tim Duncan"->"Manu Ginobili"@0] | ("Kevin Durant") | [:serve "Kevin Durant"->"Warriors"@0] | + | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Rockets") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Vince Carter") | [:serve "Grant Hill"->"Clippers"@0] | ("Jason Kidd") | [:teammate "Tony Parker"->"Manu Ginobili"@0] | ("Damian Lillard") | [:serve "Damian Lillard"->"Trail Blazers"@0] | + | | | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Tim Duncan") | [:serve "Grant Hill"->"Magic"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Manu Ginobili"@0] | ("James Harden") | [:serve "James Harden"->"Rockets"@0] | + | | | [:serve "Shaquille O'Neal"->"Magic"@0] | ("JaVale McGee") | [:serve "Grant Hill"->"Pistons"@0] | ("Marco Belinelli") | [:like "Tiago Splitter"->"Manu Ginobili"@0] | ("Chris Paul") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | + | | | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Rudy Gay") | [:serve "Grant Hill"->"Suns"@0] | ("Dejounte Murray") | [:like "Tony Parker"->"Manu Ginobili"@0] | ("LeBron James") | [:like "Russell Westbrook"->"James Harden"@0] | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Magic") | [:serve "Vince Carter"->"Grizzlies"@0] | ("Aron Baynes") | [:serve "Paul Gasol"->"Bucks"@0] | ("Steve Nash") | [:like "James Harden"->"Russell Westbrook"@0] | + | | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Spurs") | [:serve "Vince Carter"->"Hawks"@0] | ("Boris Diaw") | [:serve "Paul Gasol"->"Bulls"@0] | ("Marc Gasol") | [:serve "Chris Paul"->"Clippers"@0] | + | | | [:serve "Tracy McGrady"->"Magic"@0] | ("Celtics") | [:serve "Vince Carter"->"Kings"@0] | ("Danny Green") | [:serve "Paul Gasol"->"Grizzlies"@0] | ("Kyle Anderson") | [:serve "Chris Paul"->"Hornets"@0] | + | | | [:serve "Tracy McGrady"->"Raptors"@0] | ("Heat") | [:serve "Vince Carter"->"Magic"@0] | ("LaMarcus Aldridge") | [:serve "Paul Gasol"->"Lakers"@0] | ("Russell Westbrook") | [:serve "Chris Paul"->"Rockets"@0] | + | | | [:serve "Tracy McGrady"->"Rockets"@0] | ("Suns") | [:serve "Vince Carter"->"Mavericks"@0] | ("Tiago Splitter") | [:serve "Paul Gasol"->"Spurs"@0] | ("76ers") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | + | | | [:serve "Tracy McGrady"->"Spurs"@0] | ("Lakers") | [:serve "Vince Carter"->"Nets"@0] | ("Pistons") | [:like "Marc Gasol"->"Paul Gasol"@0] | ("Hornets") | [:like "Chris Paul"->"LeBron James"@0] | + | | | [:like "Grant Hill"->"Tracy McGrady"@0] | ("Cavaliers") | [:serve "Vince Carter"->"Raptors"@0] | ("Nets") | [:like "Paul Gasol"->"Marc Gasol"@0] | ("Bucks") | [:serve "Steve Nash"->"Lakers"@0] | + | | | [:like "Vince Carter"->"Tracy McGrady"@0] | ("Raptors") | [:serve "Vince Carter"->"Suns"@0] | ("Kings") | [:serve "Jason Kidd"->"Knicks"@0] | ("Knicks") | [:serve "Steve Nash"->"Mavericks"@0] | + | | | [:like "Tracy McGrady"->"Grant Hill"@0] | | [:like "Jason Kidd"->"Vince Carter"@0] | ("Clippers") | [:serve "Jason Kidd"->"Mavericks"@0] | ("Bulls") | [:serve "Steve Nash"->"Suns"@0] | + | | | [:like "Tracy McGrady"->"Kobe Bryant"@0] | | [:like "Vince Carter"->"Jason Kidd"@0] | ("Mavericks") | [:serve "Jason Kidd"->"Nets"@0] | ("Trail Blazers") | [:serve "Steve Nash"->"Suns"@1] | + | | | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:serve "Tim Duncan"->"Spurs"@0] | ("Hawks") | [:serve "Jason Kidd"->"Suns"@0] | ("Jazz") | [:serve "LeBron James"->"Cavaliers"@1] | + | | | | | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Warriors") | [:serve "Jason Kidd"->"Mavericks"@1] | | [:serve "LeBron James"->"Lakers"@0] | + | | | | | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Nuggets") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "LeBron James"->"Heat"@0] | + | | | | | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Grizzlies") | [:like "Steve Nash"->"Jason Kidd"@0] | | [:serve "Marc Gasol"->"Grizzlies"@0] | + | | | | | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Wizards") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Marc Gasol"->"Raptors"@0] | + | | | | | [:like "Danny Green"->"Tim Duncan"@0] | | [:like "Jason Kidd"->"Steve Nash"@0] | | [:serve "Kyle Anderson"->"Grizzlies"@0] | + | | | | | [:like "Dejounte Murray"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Hornets"@0] | | [:serve "Kyle Anderson"->"Spurs"@0] | + | | | | | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | | [:serve "Tony Parker"->"Spurs"@0] | | [:teammate "Tony Parker"->"Kyle Anderson"@0] | + | | | | | [:like "Manu Ginobili"->"Tim Duncan"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | | [:serve "LeBron James"->"Cavaliers"@0] | + | | | | | [:like "Marco Belinelli"->"Tim Duncan"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | | | + | | | | | [:like "Tiago Splitter"->"Tim Duncan"@0] | | [:like "Boris Diaw"->"Tony Parker"@0] | | | + | | | | | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | | | + | | | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | + | | | | | [:serve "JaVale McGee"->"Lakers"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Marco Belinelli"->"76ers"@0] | | | + | | | | | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Marco Belinelli"->"Bulls"@0] | | | + | | | | | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Marco Belinelli"->"Hawks"@0] | | | + | | | | | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Marco Belinelli"->"Hornets"@0] | | | + | | | | | [:serve "Rudy Gay"->"Grizzlies"@0] | | [:serve "Marco Belinelli"->"Kings"@0] | | | + | | | | | [:serve "Rudy Gay"->"Kings"@0] | | [:serve "Marco Belinelli"->"Raptors"@0] | | | + | | | | | [:serve "Rudy Gay"->"Raptors"@0] | | [:serve "Marco Belinelli"->"Spurs"@0] | | | + | | | | | [:serve "Rudy Gay"->"Spurs"@0] | | [:serve "Marco Belinelli"->"Warriors"@0] | | | + | | | | | [:like "Rudy Gay"->"LaMarcus Aldridge"@0] | | [:serve "Marco Belinelli"->"Hornets"@1] | | | + | | | | | | | [:serve "Marco Belinelli"->"Spurs"@1] | | | + | | | | | | | [:like "Danny Green"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Marco Belinelli"@0] | | | + | | | | | | | [:like "Marco Belinelli"->"Danny Green"@0] | | | + | | | | | | | [:serve "Dejounte Murray"->"Spurs"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Chris Paul"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Danny Green"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"James Harden"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kevin Durant"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Kyle Anderson"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"LeBron James"@0] | | | + | | | | | | | [:like "Dejounte Murray"->"Russell Westbrook"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Celtics"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Pistons"@0] | | | + | | | | | | | [:serve "Aron Baynes"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hawks"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Hornets"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Jazz"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Spurs"@0] | | | + | | | | | | | [:serve "Boris Diaw"->"Suns"@0] | | | + | | | | | | | [:serve "Danny Green"->"Cavaliers"@0] | | | + | | | | | | | [:serve "Danny Green"->"Raptors"@0] | | | + | | | | | | | [:serve "Danny Green"->"Spurs"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"Danny Green"@0] | | | + | | | | | | | [:like "Danny Green"->"LeBron James"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | | | + | | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | | | + | | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:like "Damian Lillard"->"LaMarcus Aldridge"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"76ers"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Hawks"@0] | | | + | | | | | | | [:serve "Tiago Splitter"->"Spurs"@0] | | | Then the result should be, in any order, with relax comparison: | _vertices | _edges | | [("Yao Ming")] | <[edge1]> | @@ -1468,21 +1468,21 @@ Feature: subgraph | [:serve "Tony Parker"->"Spurs"@0] | ("Boris Diaw") | [:teammate "Manu Ginobili"->"Tim Duncan"@0] | ("Rudy Gay") | [:serve "Aron Baynes"->"Pistons"@0] | ("Ray Allen") | [:like "Yao Ming"->"Tracy McGrady"@0] | ("Kristaps Porzingis") | [:serve "Grant Hill"->"Magic"@0] | ("Paul Gasol") | [:serve "Steve Nash"->"Mavericks"@0] | | [:teammate "Manu Ginobili"->"Tony Parker"@0] | ("LaMarcus Aldridge") | [:teammate "Tony Parker"->"Tim Duncan"@0] | ("Damian Lillard") | [:serve "Aron Baynes"->"Spurs"@0] | ("Blake Griffin") | [:serve "Ray Allen"->"Bucks"@0] | ("Dirk Nowitzki") | [:serve "Grant Hill"->"Pistons"@0] | ("Jason Kidd") | [:serve "Steve Nash"->"Suns"@0] | | [:teammate "Tim Duncan"->"Tony Parker"@0] | ("Manu Ginobili") | [:like "Aron Baynes"->"Tim Duncan"@0] | ("Kevin Durant") | [:serve "Rudy Gay"->"Grizzlies"@0] | ("Paul George") | [:serve "Ray Allen"->"Celtics"@0] | ("Rajon Rondo") | [:serve "Grant Hill"->"Suns"@0] | ("Pelicans") | [:serve "Steve Nash"->"Suns"@1] | - | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | + | [:like "Boris Diaw"->"Tony Parker"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:serve "Rudy Gay"->"Kings"@0] | ("JaVale McGee") | [:serve "Ray Allen"->"Heat"@0] | ("Vince Carter") | [:serve "Kristaps Porzingis"->"Knicks"@0] | ("Nets") | [:like "Jason Kidd"->"Steve Nash"@0] | | [:like "Dejounte Murray"->"Tony Parker"@0] | ("Dejounte Murray") | [:like "Danny Green"->"Tim Duncan"@0] | ("Tiago Splitter") | [:serve "Rudy Gay"->"Raptors"@0] | ("Luka Doncic") | [:serve "Ray Allen"->"Thunders"@0] | ("Kobe Bryant") | [:serve "Kristaps Porzingis"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Spurs"@0] | | [:like "LaMarcus Aldridge"->"Tony Parker"@0] | ("Hornets") | [:like "Dejounte Murray"->"Tim Duncan"@0] | ("Russell Westbrook") | [:serve "Rudy Gay"->"Spurs"@0] | ("Carmelo Anthony") | [:like "Rajon Rondo"->"Ray Allen"@0] | ("Wizards") | [:serve "Dirk Nowitzki"->"Mavericks"@0] | | [:like "Steve Nash"->"Jason Kidd"@0] | | [:like "Marco Belinelli"->"Tony Parker"@0] | ("Spurs") | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Danny Green") | [:like "Tracy McGrady"->"Rudy Gay"@0] | ("Tracy McGrady") | [:like "Ray Allen"->"Rajon Rondo"@0] | ("Pacers") | [:like "Jason Kidd"->"Dirk Nowitzki"@0] | | [:serve "Paul Gasol"->"Lakers"@0] | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Kyle Anderson") | [:serve "Damian Lillard"->"Trail Blazers"@0] | ("Dwyane Wade") | [:serve "Blake Griffin"->"Clippers"@0] | ("Knicks") | [:like "Steve Nash"->"Dirk Nowitzki"@0] | | [:serve "Jason Kidd"->"Knicks"@0] | | [:like "Tony Parker"->"LaMarcus Aldridge"@0] | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("James Harden") | [:serve "Kevin Durant"->"Thunders"@0] | ("Kyrie Irving") | [:serve "Blake Griffin"->"Pistons"@0] | ("Bucks") | [:like "Dirk Nowitzki"->"Jason Kidd"@0] | | [:serve "Jason Kidd"->"Mavericks"@0] | - | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | - | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquile O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | - | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquile O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | - | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquile O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | - | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquile O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | - | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquile O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | - | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquile O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | - | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquile O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | - | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | + | [:like "Tony Parker"->"Manu Ginobili"@0] | | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("LeBron James") | [:serve "Kevin Durant"->"Warriors"@0] | ("Cavaliers") | [:serve "Paul George"->"Pacers"@0] | ("Mavericks") | [:like "Dirk Nowitzki"->"Steve Nash"@0] | | [:serve "Jason Kidd"->"Nets"@0] | + | [:like "Tony Parker"->"Tim Duncan"@0] | | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Chris Paul") | [:serve "Shaquille O'Neal"->"Cavaliers"@0] | ("Celtics") | [:serve "Paul George"->"Thunders"@0] | ("Nuggets") | [:serve "Rajon Rondo"->"Bulls"@0] | | [:serve "Jason Kidd"->"Suns"@0] | + | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | ("Bulls") | [:serve "Shaquille O'Neal"->"Celtics"@0] | ("Pistons") | [:serve "JaVale McGee"->"Lakers"@0] | | [:serve "Rajon Rondo"->"Celtics"@0] | | [:serve "Jason Kidd"->"Mavericks"@1] | + | | | [:serve "Boris Diaw"->"Hawks"@0] | ("Jazz") | [:serve "Shaquille O'Neal"->"Heat"@0] | ("Grizzlies") | [:serve "JaVale McGee"->"Mavericks"@0] | | [:serve "Rajon Rondo"->"Kings"@0] | | [:serve "Paul Gasol"->"Bucks"@0] | + | | | [:serve "Boris Diaw"->"Hornets"@0] | ("Hawks") | [:serve "Shaquille O'Neal"->"Lakers"@0] | ("Heat") | [:serve "JaVale McGee"->"Nuggets"@0] | | [:serve "Rajon Rondo"->"Lakers"@0] | | [:serve "Paul Gasol"->"Bulls"@0] | + | | | [:serve "Boris Diaw"->"Jazz"@0] | ("Warriors") | [:serve "Shaquille O'Neal"->"Magic"@0] | ("Magic") | [:serve "JaVale McGee"->"Warriors"@0] | | [:serve "Rajon Rondo"->"Mavericks"@0] | | [:serve "Paul Gasol"->"Grizzlies"@0] | + | | | [:serve "Boris Diaw"->"Spurs"@0] | ("Suns") | [:serve "Shaquille O'Neal"->"Suns"@0] | ("Lakers") | [:serve "JaVale McGee"->"Wizards"@0] | | [:serve "Rajon Rondo"->"Pelicans"@0] | | | + | | | [:serve "Boris Diaw"->"Suns"@0] | ("Trail Blazers") | [:like "Yao Ming"->"Shaquille O'Neal"@0] | ("Clippers") | [:serve "Luka Doncic"->"Mavericks"@0] | | [:serve "Vince Carter"->"Grizzlies"@0] | | | + | | | [:serve "LaMarcus Aldridge"->"Spurs"@0] | ("Kings") | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | ("Thunders") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | [:serve "Vince Carter"->"Hawks"@0] | | | | | | [:serve "LaMarcus Aldridge"->"Trail Blazers"@0] | ("Raptors") | [:serve "Tiago Splitter"->"76ers"@0] | ("Rockets") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | [:serve "Vince Carter"->"Kings"@0] | | | | | | [:teammate "Tim Duncan"->"LaMarcus Aldridge"@0] | ("76ers") | [:serve "Tiago Splitter"->"Hawks"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | [:serve "Vince Carter"->"Magic"@0] | | | | | | [:teammate "Tony Parker"->"LaMarcus Aldridge"@0] | | [:serve "Tiago Splitter"->"Spurs"@0] | | [:serve "Carmelo Anthony"->"Knicks"@0] | | [:serve "Vince Carter"->"Mavericks"@0] | | | @@ -1540,8 +1540,8 @@ Feature: subgraph | [:like "LaMarcus Aldridge"->"Tim Duncan"@0] | ("Marco Belinelli") | [:like "Boris Diaw"->"Tony Parker"@0] | ("Rudy Gay") | [:like "Carmelo Anthony"->"Chris Paul"@0] | ("Dwyane Wade") | [:like "Dwyane Wade"->"Carmelo Anthony"@0] | ("Rajon Rondo") | | [:like "Manu Ginobili"->"Tim Duncan"@0] | ("Aron Baynes") | [:like "Dejounte Murray"->"Chris Paul"@0] | ("Kyle Anderson") | [:like "Dwyane Wade"->"Chris Paul"@0] | ("Kyrie Irving") | [:like "Carmelo Anthony"->"Dwyane Wade"@0] | ("Kristaps Porzingis") | | [:like "Marco Belinelli"->"Tim Duncan"@0] | ("Manu Ginobili") | [:like "Dejounte Murray"->"Danny Green"@0] | ("LeBron James") | [:like "Chris Paul"->"Carmelo Anthony"@0] | ("Ray Allen") | [:like "Kristaps Porzingis"->"Luka Doncic"@0] | | - | [:like "Shaquile O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | - | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquile O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | + | [:like "Shaquille O'Neal"->"Tim Duncan"@0] | ("Tiago Splitter") | [:like "Dejounte Murray"->"James Harden"@0] | ("Russell Westbrook") | [:like "Chris Paul"->"Dwyane Wade"@0] | ("Paul George") | [:like "Luka Doncic"->"Dirk Nowitzki"@0] | | + | [:like "Tiago Splitter"->"Tim Duncan"@0] | ("Shaquille O'Neal") | [:like "Dejounte Murray"->"Kevin Durant"@0] | ("Yao Ming") | [:like "Chris Paul"->"LeBron James"@0] | | [:like "Luka Doncic"->"Kristaps Porzingis"@0] | | | [:like "Tony Parker"->"Tim Duncan"@0] | ("Tony Parker") | [:like "Dejounte Murray"->"Kyle Anderson"@0] | ("JaVale McGee") | [:like "Tracy McGrady"->"Rudy Gay"@0] | | [:like "Dirk Nowitzki"->"Dwyane Wade"@0] | | | [:like "Tim Duncan"->"Manu Ginobili"@0] | | [:like "Dejounte Murray"->"LeBron James"@0] | | [:like "Carmelo Anthony"->"LeBron James"@0] | | [:like "Rajon Rondo"->"Ray Allen"@0] | | | [:like "Tim Duncan"->"Tony Parker"@0] | | [:like "Dejounte Murray"->"Manu Ginobili"@0] | | [:like "Dwyane Wade"->"LeBron James"@0] | | [:like "Ray Allen"->"Rajon Rondo"@0] | | @@ -1554,8 +1554,8 @@ Feature: subgraph | | | [:like "Marco Belinelli"->"Tony Parker"@0] | | | | | | | | | [:like "Tiago Splitter"->"Manu Ginobili"@0] | | | | | | | | | [:like "Tony Parker"->"Manu Ginobili"@0] | | | | | | - | | | [:like "Yao Ming"->"Shaquile O'Neal"@0] | | | | | | - | | | [:like "Shaquile O'Neal"->"JaVale McGee"@0] | | | | | | + | | | [:like "Yao Ming"->"Shaquille O'Neal"@0] | | | | | | + | | | [:like "Shaquille O'Neal"->"JaVale McGee"@0] | | | | | | Then the result should be, in any order, with relax comparison: | _vertices | _edges | | [("Tim Duncan")] | <[edge1]> | diff --git a/tests/tck/features/update/Update.IntVid.feature b/tests/tck/features/update/Update.IntVid.feature index efa1149fb2a..a6d75cb8b1f 100644 --- a/tests/tck/features/update/Update.IntVid.feature +++ b/tests/tck/features/update/Update.IntVid.feature @@ -96,7 +96,7 @@ Feature: Update int vid of vertex and edge """ UPDATE VERTEX 101 SET course.credits = $^.course.credits + 1 - WHEN $^.course.name == "notexist" AND $^.course.credits > 2 + WHEN $^.course.name == "nonexistent" AND $^.course.credits > 2 YIELD $^.course.name AS Name, $^.course.credits AS Credits """ Then the result should be, in any order: diff --git a/tests/tck/features/update/Update.feature b/tests/tck/features/update/Update.feature index f77f39680a5..7a7f3407a45 100644 --- a/tests/tck/features/update/Update.feature +++ b/tests/tck/features/update/Update.feature @@ -98,7 +98,7 @@ Feature: Update string vid of vertex and edge """ UPDATE VERTEX "101" SET course.credits = $^.course.credits + 1 - WHEN $^.course.name == "notexist" AND $^.course.credits > 2 + WHEN $^.course.name == "nonexistent" AND $^.course.credits > 2 YIELD $^.course.name AS Name, $^.course.credits AS Credits """ Then the result should be, in any order: @@ -741,7 +741,7 @@ Feature: Update string vid of vertex and edge """ UPDATE VERTEX ON course "101" SET credits = credits + 1 - WHEN name == "notexist" AND credits > 2 + WHEN name == "nonexistent" AND credits > 2 YIELD name AS Name, credits AS Credits """ Then the result should be, in any order: diff --git a/tests/tck/features/verify_client_version/VerifyClientVersion.feature b/tests/tck/features/verify_client_version/VerifyClientVersion.feature index b454a32ae96..5021efc64bb 100644 --- a/tests/tck/features/verify_client_version/VerifyClientVersion.feature +++ b/tests/tck/features/verify_client_version/VerifyClientVersion.feature @@ -8,7 +8,7 @@ Feature: Verify client version When connecting the servers with a compatible client version Then the connection should be established - Scenario: incompactible version + Scenario: incompatible version Given nothing When connecting the servers with a client version of 100.0.0 Then the connection should be rejected diff --git a/tests/tck/job/Job.feature b/tests/tck/job/Job.feature index 1d683d55dad..cd41904c8bd 100644 --- a/tests/tck/job/Job.feature +++ b/tests/tck/job/Job.feature @@ -179,7 +179,7 @@ Feature: Submit job space requirements """ Then an ExecutionError should be raised at runtime:Job not in chosen space! - # This is skipped becuase it is hard to simulate the situation + # This is skipped because it is hard to simulate the situation # When executing query: # """ # RECOVER JOB; diff --git a/tests/tck/openCypher/features/expressions/map/Map1.feature b/tests/tck/openCypher/features/expressions/map/Map1.feature index ac7cc6d254a..3ca97a3271a 100644 --- a/tests/tck/openCypher/features/expressions/map/Map1.feature +++ b/tests/tck/openCypher/features/expressions/map/Map1.feature @@ -19,7 +19,7 @@ Feature: Map1 - Static value access @uncompatible Scenario: [2] Fail when performing property access on a non-map - # openCyter return : TypeError should be raised at runtime: PropertyAccessOnNonMap + # openCypher return : TypeError should be raised at runtime: PropertyAccessOnNonMap When executing query: """ WITH [{num: 0}, 1] AS list diff --git a/third-party/install-gcc.sh b/third-party/install-gcc.sh index b21509972fb..3e27aa49252 100755 --- a/third-party/install-gcc.sh +++ b/third-party/install-gcc.sh @@ -35,7 +35,7 @@ this_distro=$(lsb_release -si) this_libc_version=$(ldd --version | head -1 | cut -d ')' -f 2 | cut -d ' ' -f 2) hash wget &>/dev/null || { - echo "'wget' not fould, please install it first" 1>&2 + echo "'wget' not found, please install it first" 1>&2 exit 1 } diff --git a/third-party/install-third-party.sh b/third-party/install-third-party.sh index 2acc31c24c9..5ed1f5dbad7 100755 --- a/third-party/install-third-party.sh +++ b/third-party/install-third-party.sh @@ -37,7 +37,7 @@ this_gcc_version=$($cxx_cmd -dumpfullversion -dumpversion) this_abi_version=$($this_dir/cxx-compiler-abi-version.sh) hash wget &>/dev/null || { - echo "'wget' not fould, please install it first" 1>&2 + echo "'wget' not found, please install it first" 1>&2 exit 1 }