diff --git a/.coveragerc b/.coveragerc index 9fdcce71f..5eace57be 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,6 +1,13 @@ [run] -# We don't want to include the tests themselves in the coverage report -omit = graphql_compiler/tests/* +omit = + # No coverage for tests + graphql_compiler/tests/* + + # No coverage for SQL command generation script + scripts/generate_test_sql/* + + # No coverage for snapshots. + **/snap_*.py [report] # Regexes for lines to exclude from consideration diff --git a/.gitignore b/.gitignore index e621c94d3..45508e04f 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,8 @@ tools/sphinx_docgen/docs_html # Python package publishing directories build/ dist/ + +# vim and swap files +*.vim +*.swp +*.swo diff --git a/.travis.yml b/.travis.yml index e7fea7b95..5840092ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,16 +4,21 @@ cache: pip python: - "2.7" - "3.6" +services: + - docker install: - pip install -r dev-requirements.txt - pip install -e . +before_script: + - docker-compose up -d script: - ./scripts/copyright_line_check.sh - isort --check-only --verbose --recursive graphql_compiler/ - - flake8 graphql_compiler/ + - flake8 --exclude **/snap_*.py graphql_compiler/ - pydocstyle graphql_compiler/ - pylint graphql_compiler/ - bandit -r graphql_compiler/ - py.test --cov=graphql_compiler graphql_compiler/tests after_success: + - docker-compose down - coveralls diff --git a/dev-requirements.txt b/dev-requirements.txt index 27bf9a136..d8afbb7b7 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -4,5 +4,7 @@ flake8==3.5.0 isort==4.3.4 pydocstyle==2.1.1 pylint==1.8.2 +pyorient==1.5.5 pytest==3.4.1 pytest-cov==2.5.1 +snapshottest==0.5.0 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..0a72bcbe4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: '3' +services: + orientdb: + image: orientdb:2.2.30 + command: server.sh + ports: + - "127.0.0.1:2480:2480" + - "127.0.0.1:2424:2424" + environment: + ORIENTDB_ROOT_PASSWORD: root diff --git a/graphql_compiler/tests/conftest.py b/graphql_compiler/tests/conftest.py new file mode 100644 index 000000000..91326a095 --- /dev/null +++ b/graphql_compiler/tests/conftest.py @@ -0,0 +1,40 @@ +# Copyright 2018-present Kensho Technologies, LLC. +import sys +import time + +import pytest + +from .test_data_tools.graph import get_test_graph + + +# Pytest fixtures depend on name redefinitions to work, +# so this check generates tons of false-positives here. +# pylint: disable=redefined-outer-name + + +@pytest.fixture(scope='session') +def init_graph(): + """Return a client for an initialized db, with all test data imported.""" + graph_name = 'animals' + + # Try to set up the database for the test up to 20 times before giving up. + set_up_successfully = False + for _ in range(20): + try: + graph_client = get_test_graph(graph_name) + set_up_successfully = True + break + except Exception as e: # pylint: disable=broad-except + sys.stderr.write(u'Failed to set up test DB: {}'.format(e)) + time.sleep(1) + + if not set_up_successfully: + raise AssertionError(u'Failed to set up database without raising an exception!') + + return graph_client + + +@pytest.fixture(scope='class') +def graph_client(request, init_graph): + """Get a client for an initialized db, with all test data imported.""" + request.cls.graph_client = init_graph diff --git a/graphql_compiler/tests/snapshot_tests/__init__.py b/graphql_compiler/tests/snapshot_tests/__init__.py new file mode 100644 index 000000000..5bdcb1f8e --- /dev/null +++ b/graphql_compiler/tests/snapshot_tests/__init__.py @@ -0,0 +1 @@ +# Copyright 2018-present Kensho Technologies, LLC. diff --git a/graphql_compiler/tests/snapshot_tests/snapshots/__init__.py b/graphql_compiler/tests/snapshot_tests/snapshots/__init__.py new file mode 100644 index 000000000..5bdcb1f8e --- /dev/null +++ b/graphql_compiler/tests/snapshot_tests/snapshots/__init__.py @@ -0,0 +1 @@ +# Copyright 2018-present Kensho Technologies, LLC. diff --git a/graphql_compiler/tests/snapshot_tests/snapshots/snap_test_orientdb_match_query.py b/graphql_compiler/tests/snapshot_tests/snapshots/snap_test_orientdb_match_query.py new file mode 100644 index 000000000..ebb9599a9 --- /dev/null +++ b/graphql_compiler/tests/snapshot_tests/snapshots/snap_test_orientdb_match_query.py @@ -0,0 +1,23 @@ +# Copyright 2018-present Kensho Technologies, LLC. +# -*- coding: utf-8 -*- +# snapshottest: v1 - https://goo.gl/zC4yUc +from __future__ import unicode_literals + +from snapshottest import Snapshot + + +snapshots = Snapshot() + +snapshots['OrientDBMatchQueryTests::test_filter_in_optional_block 1'] = frozenset([(frozenset([('animal_name', 'Pteranodon__4')]), 1), (frozenset([('animal_name', 'Nazgul__3')]), 1), (frozenset([('parent_name', 'Nazgul__2'), ('animal_name', 'Nazgul__(234)'), ('uuid', '8b0163c1-cd9d-2b7d-247a-8333f7b0b7d2')]), 1), (frozenset([('animal_name', 'Nazgul__1')]), 1), (frozenset([('parent_name', 'Nazgul__2'), ('uuid', '8b0163c1-cd9d-2b7d-247a-8333f7b0b7d2'), ('animal_name', 'Nazgul__((013)24)')]), 1), (frozenset([('animal_name', 'Dragon__2')]), 1), (frozenset([('animal_name', 'Nazgul__0')]), 1), (frozenset([('animal_name', 'Hippogriff__4')]), 1), (frozenset([('animal_name', 'Dragon__3')]), 1), (frozenset([('parent_name', 'Nazgul__2'), ('animal_name', 'Nazgul__(024)'), ('uuid', '8b0163c1-cd9d-2b7d-247a-8333f7b0b7d2')]), 1), (frozenset([('animal_name', 'Hippogriff__2')]), 1), (frozenset([('animal_name', 'Dragon__1')]), 1), (frozenset([('animal_name', 'Dragon__0')]), 1), (frozenset([('animal_name', 'Nazgul__4')]), 1), (frozenset([('animal_name', 'Pteranodon__0')]), 1), (frozenset([('animal_name', 'Pteranodon__1')]), 1), (frozenset([('parent_name', 'Nazgul__2'), ('animal_name', 'Nazgul__((((234)34)01)24)'), ('uuid', '8b0163c1-cd9d-2b7d-247a-8333f7b0b7d2')]), 1), (frozenset([('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Dragon__4')]), 1), (frozenset([('animal_name', 'Pteranodon__3')]), 1), (frozenset([('animal_name', 'Hippogriff__1')]), 1), (frozenset([('animal_name', 'Hippogriff__3')]), 1), (frozenset([('animal_name', 'Pteranodon__2')]), 1), (frozenset([('animal_name', 'Nazgul__2')]), 1)]) + +snapshots['OrientDBMatchQueryTests::test_fold_on_output_variable 1'] = frozenset([(frozenset([('child_names_list', ('Pteranodon__(((034)02)((034)04)3)', 'Pteranodon__(034)', 'Pteranodon__3')), ('animal_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)')]), 1), (frozenset([('animal_name', 'Nazgul__((234)34)'), ('child_names_list', ('Nazgul__(234)', 'Nazgul__3', 'Nazgul__4'))]), 1), (frozenset([('child_names_list', ('Nazgul__0', 'Nazgul__2', 'Nazgul__4')), ('animal_name', 'Nazgul__(024)')]), 1), (frozenset([('animal_name', 'Nazgul__3'), ('child_names_list', ())]), 1), (frozenset([('child_names_list', ('Nazgul__((234)34)', 'Nazgul__0', 'Nazgul__1')), ('animal_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('animal_name', 'Nazgul__((((234)34)01)24)'), ('child_names_list', ('Nazgul__(((234)34)01)', 'Nazgul__2', 'Nazgul__4'))]), 1), (frozenset([('animal_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))'), ('child_names_list', ('Dragon__(((((024)34)04)02)23)', 'Dragon__((024)34)', 'Dragon__(024)'))]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('child_names_list', ())]), 1), (frozenset([('animal_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('child_names_list', ('Hippogriff__(((((134)14)02)34)(134)0)', 'Hippogriff__((134)14)', 'Hippogriff__3'))]), 1), (frozenset([('child_names_list', ()), ('animal_name', 'Pteranodon__0')]), 1), (frozenset([('child_names_list', ('Hippogriff__((((134)14)02)34)', 'Hippogriff__(134)', 'Hippogriff__0')), ('animal_name', 'Hippogriff__(((((134)14)02)34)(134)0)')]), 1), (frozenset([('child_names_list', ()), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('child_names_list', ())]), 1), (frozenset([('animal_name', 'Hippogriff__4'), ('child_names_list', ())]), 1), (frozenset([('animal_name', 'Dragon__(((((024)34)04)02)23)'), ('child_names_list', ('Dragon__((((024)34)04)02)', 'Dragon__2', 'Dragon__3'))]), 1), (frozenset([('animal_name', 'Dragon__(((024)12)(024)3)'), ('child_names_list', ('Dragon__((024)12)', 'Dragon__(024)', 'Dragon__3'))]), 1), (frozenset([('child_names_list', ('Pteranodon__((034)02)', 'Pteranodon__1', 'Pteranodon__3')), ('animal_name', 'Pteranodon__(((034)02)13)')]), 1), (frozenset([('child_names_list', ('Dragon__(024)', 'Dragon__3', 'Dragon__4')), ('animal_name', 'Dragon__((024)34)')]), 1), (frozenset([('child_names_list', ('Hippogriff__(134)', 'Hippogriff__1', 'Hippogriff__4')), ('animal_name', 'Hippogriff__((134)14)')]), 1), (frozenset([('animal_name', 'Dragon__((((024)34)04)02)'), ('child_names_list', ('Dragon__(((024)34)04)', 'Dragon__0', 'Dragon__2'))]), 1), (frozenset([('child_names_list', ('Nazgul__0', 'Nazgul__1', 'Nazgul__3')), ('animal_name', 'Nazgul__(013)')]), 1), (frozenset([('child_names_list', ('Hippogriff__(134)', 'Hippogriff__3', 'Hippogriff__4')), ('animal_name', 'Hippogriff__((134)34)')]), 1), (frozenset([('animal_name', 'Pteranodon__(((034)02)23)'), ('child_names_list', ('Pteranodon__((034)02)', 'Pteranodon__2', 'Pteranodon__3'))]), 1), (frozenset([('child_names_list', ('Dragon__0', 'Dragon__2', 'Dragon__4')), ('animal_name', 'Dragon__(024)')]), 1), (frozenset([('animal_name', 'Nazgul__((013)(234)0)'), ('child_names_list', ('Nazgul__(013)', 'Nazgul__(234)', 'Nazgul__0'))]), 1), (frozenset([('child_names_list', ('Hippogriff__0', 'Hippogriff__2', 'Hippogriff__4')), ('animal_name', 'Hippogriff__(024)')]), 1), (frozenset([('animal_name', 'Hippogriff__2'), ('child_names_list', ())]), 1), (frozenset([('animal_name', 'Hippogriff__((((134)14)02)34)'), ('child_names_list', ('Hippogriff__(((134)14)02)', 'Hippogriff__3', 'Hippogriff__4'))]), 1), (frozenset([('animal_name', 'Hippogriff__(((134)14)02)'), ('child_names_list', ('Hippogriff__((134)14)', 'Hippogriff__0', 'Hippogriff__2'))]), 1), (frozenset([('child_names_list', ()), ('animal_name', 'Dragon__4')]), 1), (frozenset([('child_names_list', ()), ('animal_name', 'Hippogriff__1')]), 1), (frozenset([('child_names_list', ('Pteranodon__(034)', 'Pteranodon__0', 'Pteranodon__2')), ('animal_name', 'Pteranodon__((034)02)')]), 1), (frozenset([('animal_name', 'Dragon__0'), ('child_names_list', ())]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('child_names_list', ('Pteranodon__(((034)02)13)', 'Pteranodon__(((034)02)23)', 'Pteranodon__(034)'))]), 1), (frozenset([('child_names_list', ('Nazgul__((013)(234)0)', 'Nazgul__((024)(234)3)', 'Nazgul__(024)')), ('animal_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))')]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)13)13)'), ('child_names_list', ('Pteranodon__(((034)02)13)', 'Pteranodon__1', 'Pteranodon__3'))]), 1), (frozenset([('child_names_list', ()), ('animal_name', 'Dragon__1')]), 1), (frozenset([('child_names_list', ('Dragon__((024)34)', 'Dragon__0', 'Dragon__4')), ('animal_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('child_names_list', ('Pteranodon__(034)', 'Pteranodon__0', 'Pteranodon__4')), ('animal_name', 'Pteranodon__((034)04)')]), 1), (frozenset([('child_names_list', ('Nazgul__(024)', 'Nazgul__(234)', 'Nazgul__3')), ('animal_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('child_names_list', ('Hippogriff__(((((134)14)02)34)(134)0)', 'Hippogriff__(134)', 'Hippogriff__4')), ('animal_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)')]), 1), (frozenset([('animal_name', 'Dragon__3'), ('child_names_list', ())]), 1), (frozenset([('animal_name', 'Pteranodon__1'), ('child_names_list', ())]), 1), (frozenset([('child_names_list', ('Pteranodon__0', 'Pteranodon__3', 'Pteranodon__4')), ('animal_name', 'Pteranodon__(034)')]), 1), (frozenset([('child_names_list', ()), ('animal_name', 'Hippogriff__3')]), 1), (frozenset([('child_names_list', ('Dragon__((((024)34)04)02)', 'Dragon__((024)34)', 'Dragon__0')), ('animal_name', 'Dragon__(((((024)34)04)02)((024)34)0)')]), 1), (frozenset([('child_names_list', ('Dragon__(024)', 'Dragon__1', 'Dragon__2')), ('animal_name', 'Dragon__((024)12)')]), 1), (frozenset([('child_names_list', ('Dragon__(((((024)34)04)02)23)', 'Dragon__((((024)34)04)02)', 'Dragon__2')), ('animal_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_names_list', ('Hippogriff__1', 'Hippogriff__3', 'Hippogriff__4'))]), 1), (frozenset([('child_names_list', ()), ('animal_name', 'Nazgul__4')]), 1), (frozenset([('animal_name', 'Nazgul__((013)24)'), ('child_names_list', ('Nazgul__(013)', 'Nazgul__2', 'Nazgul__4'))]), 1), (frozenset([('animal_name', 'Dragon__2'), ('child_names_list', ())]), 1), (frozenset([('animal_name', 'Nazgul__0'), ('child_names_list', ())]), 1), (frozenset([('animal_name', 'Hippogriff__((134)03)'), ('child_names_list', ('Hippogriff__(134)', 'Hippogriff__0', 'Hippogriff__3'))]), 1), (frozenset([('animal_name', 'Nazgul__(234)'), ('child_names_list', ('Nazgul__2', 'Nazgul__3', 'Nazgul__4'))]), 1), (frozenset([('animal_name', 'Pteranodon__2'), ('child_names_list', ())]), 1), (frozenset([('child_names_list', ()), ('animal_name', 'Nazgul__1')]), 1), (frozenset([('child_names_list', ('Pteranodon__((034)02)', 'Pteranodon__((034)04)', 'Pteranodon__3')), ('animal_name', 'Pteranodon__(((034)02)((034)04)3)')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('child_names_list', ())]), 1), (frozenset([('animal_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('child_names_list', ('Pteranodon__((((034)02)13)(((034)02)23)(034))', 'Pteranodon__(034)', 'Pteranodon__4'))]), 1)]) + +snapshots['OrientDBMatchQueryTests::test_immediate_output 1'] = frozenset([(frozenset([('animal_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('animal_name', 'Nazgul__(024)')]), 1), (frozenset([('animal_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)')]), 1), (frozenset([('animal_name', 'Pteranodon__4')]), 1), (frozenset([('animal_name', 'Dragon__2')]), 1), (frozenset([('animal_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('animal_name', 'Pteranodon__(((034)02)23)')]), 1), (frozenset([('animal_name', 'Nazgul__((013)(234)0)')]), 1), (frozenset([('animal_name', 'Hippogriff__((134)14)')]), 1), (frozenset([('animal_name', 'Dragon__((024)34)')]), 1), (frozenset([('animal_name', 'Nazgul__1')]), 1), (frozenset([('animal_name', 'Dragon__((((024)34)04)02)')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)')]), 1), (frozenset([('animal_name', 'Nazgul__0')]), 1), (frozenset([('animal_name', 'Dragon__(((024)12)(024)3)')]), 1), (frozenset([('animal_name', 'Pteranodon__((034)04)')]), 1), (frozenset([('animal_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))')]), 1), (frozenset([('animal_name', 'Hippogriff__4')]), 1), (frozenset([('animal_name', 'Pteranodon__(((034)02)((034)04)3)')]), 1), (frozenset([('animal_name', 'Hippogriff__(((134)14)02)')]), 1), (frozenset([('animal_name', 'Hippogriff__(024)')]), 1), (frozenset([('animal_name', 'Dragon__3')]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))')]), 1), (frozenset([('animal_name', 'Hippogriff__(((((134)14)02)34)(134)0)')]), 1), (frozenset([('animal_name', 'Hippogriff__2')]), 1), (frozenset([('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Dragon__1')]), 1), (frozenset([('animal_name', 'Dragon__((024)12)')]), 1), (frozenset([('animal_name', 'Hippogriff__((134)34)')]), 1), (frozenset([('animal_name', 'Nazgul__3')]), 1), (frozenset([('animal_name', 'Dragon__(((((024)34)04)02)23)')]), 1), (frozenset([('animal_name', 'Dragon__0')]), 1), (frozenset([('animal_name', 'Nazgul__4')]), 1), (frozenset([('animal_name', 'Nazgul__((013)24)')]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)13)13)')]), 1), (frozenset([('animal_name', 'Pteranodon__0')]), 1), (frozenset([('animal_name', 'Pteranodon__(((034)02)13)')]), 1), (frozenset([('animal_name', 'Nazgul__(013)')]), 1), (frozenset([('animal_name', 'Pteranodon__1')]), 1), (frozenset([('animal_name', 'Pteranodon__((034)02)')]), 1), (frozenset([('animal_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)')]), 1), (frozenset([('animal_name', 'Hippogriff__((134)03)')]), 1), (frozenset([('animal_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)')]), 1), (frozenset([('animal_name', 'Pteranodon__(034)')]), 1), (frozenset([('animal_name', 'Pteranodon__2')]), 1), (frozenset([('animal_name', 'Dragon__4')]), 1), (frozenset([('animal_name', 'Nazgul__(234)')]), 1), (frozenset([('animal_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)')]), 1), (frozenset([('animal_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)')]), 1), (frozenset([('animal_name', 'Pteranodon__3')]), 1), (frozenset([('animal_name', 'Dragon__(024)')]), 1), (frozenset([('animal_name', 'Nazgul__((234)34)')]), 1), (frozenset([('animal_name', 'Hippogriff__1')]), 1), (frozenset([('animal_name', 'Nazgul__((((234)34)01)24)')]), 1), (frozenset([('animal_name', 'Hippogriff__3')]), 1), (frozenset([('animal_name', 'Hippogriff__((((134)14)02)34)')]), 1), (frozenset([('animal_name', 'Nazgul__2')]), 1), (frozenset([('animal_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('animal_name', 'Dragon__(((((024)34)04)02)((024)34)0)')]), 1)]) + +snapshots['OrientDBMatchQueryTests::test_optional_and_deep_traverse 1'] = frozenset([(frozenset([('spouse_and_self_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((((024)34)04)02)'), ('child_name', 'Dragon__(((((024)34)04)02)23)')]), 1), (frozenset([('animal_name', 'Hippogriff__4'), ('spouse_and_self_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__((134)34)')]), 1), (frozenset([('child_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__((013)(234)0)'), ('spouse_and_self_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('animal_name', 'Pteranodon__2'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__0'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__(024)'), ('animal_name', 'Dragon__4')]), 1), (frozenset([('child_name', 'Hippogriff__((134)03)'), ('spouse_and_self_name', 'Hippogriff__(134)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Hippogriff__((134)34)')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__(034)'), ('animal_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__4'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(024)'), ('animal_name', 'Nazgul__4'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__3'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)13)13)')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__(((034)02)23)'), ('animal_name', 'Pteranodon__(((034)02)23)'), ('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__1'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3'), ('child_name', 'Hippogriff__(134)')]), 1), (frozenset([('animal_name', 'Hippogriff__((((134)14)02)34)'), ('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('animal_name', 'Dragon__(((((024)34)04)02)((024)34)0)')]), 1), (frozenset([('child_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)'), ('animal_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('child_name', 'Hippogriff__((134)03)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__((((134)14)02)34)'), ('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('child_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__((013)(234)0)'), ('animal_name', 'Nazgul__((013)(234)0)')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('child_name', 'Dragon__(((024)12)(024)3)')]), 1), (frozenset([('spouse_species', 'Pteranodon'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('animal_name', 'Pteranodon__0'), ('child_name', 'Pteranodon__((034)02)')]), 1), (frozenset([('child_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('spouse_and_self_name', 'Pteranodon__4'), ('animal_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__3'), ('animal_name', 'Nazgul__4'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('spouse_species', 'Pteranodon'), ('spouse_and_self_name', 'Pteranodon__4'), ('animal_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((034)04)')]), 1), (frozenset([('animal_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('spouse_and_self_name', 'Hippogriff__1'), ('child_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Nazgul__(013)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)(234)0)'), ('spouse_and_self_name', 'Nazgul__(013)')]), 1), (frozenset([('animal_name', 'Dragon__0'), ('spouse_and_self_name', 'Dragon__((024)34)'), ('child_name', 'Dragon__(((024)34)04)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_and_self_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Dragon'), ('child_name', 'Dragon__(((024)34)04)'), ('animal_name', 'Dragon__4'), ('spouse_and_self_name', 'Dragon__4')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__0'), ('animal_name', 'Dragon__0'), ('child_name', 'Dragon__(((024)34)04)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__3'), ('animal_name', 'Pteranodon__((034)04)'), ('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__4'), ('animal_name', 'Nazgul__4')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)'), ('animal_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__(((234)34)01)'), ('spouse_and_self_name', 'Nazgul__((234)34)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__4'), ('animal_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__((((134)14)02)34)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)'), ('animal_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_and_self_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__0'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__((((024)34)04)02)'), ('animal_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__(034)'), ('animal_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__3'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__3'), ('child_name', 'Dragon__(((((024)34)04)02)23)')]), 1), (frozenset([('child_name', 'Dragon__(((((024)34)04)02)((024)34)0)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((((024)34)04)02)'), ('spouse_and_self_name', 'Dragon__((024)34)')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('spouse_and_self_name', 'Dragon__3'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__(((((024)34)04)02)23)')]), 1), (frozenset([('spouse_species', 'Pteranodon'), ('animal_name', 'Pteranodon__0'), ('spouse_and_self_name', 'Pteranodon__0'), ('child_name', 'Pteranodon__((034)02)')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((024)34)'), ('child_name', 'Dragon__(((024)34)04)'), ('spouse_and_self_name', 'Dragon__4')]), 1), (frozenset([('animal_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)'), ('spouse_and_self_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__3'), ('spouse_and_self_name', 'Nazgul__3'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_and_self_name', 'Pteranodon__(((034)02)13)'), ('spouse_species', 'Pteranodon'), ('child_name', 'Pteranodon__((((034)02)13)13)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('child_name', 'Hippogriff__(((134)14)02)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__((134)14)')]), 1), (frozenset([('child_name', 'Dragon__(((((024)34)04)02)((024)34)0)'), ('animal_name', 'Dragon__0'), ('spouse_and_self_name', 'Dragon__((024)34)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__4'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__(024)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('animal_name', 'Dragon__(((024)12)(024)3)')]), 1), (frozenset([('animal_name', 'Hippogriff__4'), ('spouse_and_self_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('child_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)'), ('spouse_and_self_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((024)34)'), ('spouse_and_self_name', 'Dragon__(((((024)34)04)02)23)'), ('child_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__3'), ('spouse_and_self_name', 'Nazgul__(024)'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('animal_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__((134)34)'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__3'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('child_name', 'Dragon__((024)34)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__((((134)14)02)34)'), ('animal_name', 'Hippogriff__((((134)14)02)34)'), ('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('child_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)'), ('animal_name', 'Dragon__((((024)34)04)02)'), ('spouse_and_self_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__(234)'), ('animal_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('child_name', 'Dragon__(((((024)34)04)02)((024)34)0)'), ('spouse_and_self_name', 'Dragon__0'), ('animal_name', 'Dragon__0'), ('spouse_species', 'Dragon')]), 1), (frozenset([('child_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__(024)'), ('spouse_and_self_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((((234)34)01)24)'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__0'), ('animal_name', 'Nazgul__(234)'), ('child_name', 'Nazgul__((013)(234)0)'), ('spouse_species', 'Nazgul')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__1'), ('animal_name', 'Hippogriff__1'), ('child_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__0'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(024)'), ('animal_name', 'Nazgul__4')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)13)'), ('animal_name', 'Pteranodon__1'), ('spouse_and_self_name', 'Pteranodon__3'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('child_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('animal_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((034)02)'), ('spouse_and_self_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__2'), ('animal_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__(024)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__3'), ('animal_name', 'Hippogriff__1'), ('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__(134)')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(((034)02)23)'), ('spouse_and_self_name', 'Pteranodon__2'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Hippogriff__2'), ('child_name', 'Hippogriff__(((134)14)02)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__2')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_and_self_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Dragon__0'), ('child_name', 'Dragon__(024)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('child_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)'), ('spouse_and_self_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__(((034)02)23)'), ('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('animal_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__((134)14)'), ('animal_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__0'), ('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__((013)(234)0)'), ('spouse_species', 'Nazgul')]), 1), (frozenset([('child_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))'), ('spouse_and_self_name', 'Nazgul__(024)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__((013)(234)0)')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__3'), ('animal_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Hippogriff__4'), ('spouse_and_self_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('child_name', 'Hippogriff__((134)03)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__3'), ('child_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((((234)34)01)24)'), ('spouse_and_self_name', 'Nazgul__4')]), 1), (frozenset([('animal_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))')]), 1), (frozenset([('animal_name', 'Dragon__0'), ('child_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('animal_name', 'Dragon__0'), ('child_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(024)'), ('spouse_and_self_name', 'Nazgul__4'), ('animal_name', 'Nazgul__4')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__((034)02)'), ('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('animal_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__1'), ('spouse_and_self_name', 'Nazgul__1'), ('child_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__(((034)02)13)'), ('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('spouse_species', 'Pteranodon'), ('animal_name', 'Pteranodon__(((034)02)13)')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('spouse_and_self_name', 'Dragon__0'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__(024)')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__(((034)02)23)'), ('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('spouse_species', 'Pteranodon'), ('animal_name', 'Pteranodon__(((034)02)13)')]), 1), (frozenset([('child_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__((024)(234)3)'), ('spouse_and_self_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('animal_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__(024)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Nazgul__((234)34)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(((234)34)01)'), ('spouse_and_self_name', 'Nazgul__1')]), 1), (frozenset([('child_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__((013)(234)0)'), ('animal_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('child_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('spouse_and_self_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('animal_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Nazgul__(013)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)(234)0)'), ('spouse_and_self_name', 'Nazgul__(234)')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__3'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((((024)34)04)02)'), ('child_name', 'Dragon__(((((024)34)04)02)23)')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('child_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('animal_name', 'Pteranodon__(034)'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((134)03)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__3')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('child_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__4')]), 1), (frozenset([('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__((024)34)'), ('child_name', 'Dragon__(((024)34)04)'), ('animal_name', 'Dragon__4')]), 1), (frozenset([('spouse_species', 'Pteranodon'), ('animal_name', 'Pteranodon__(034)'), ('spouse_and_self_name', 'Pteranodon__0'), ('child_name', 'Pteranodon__((034)04)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__1'), ('animal_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__(134)')]), 1), (frozenset([('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)'), ('animal_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__(((034)02)13)'), ('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('animal_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Nazgul__(013)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)(234)0)'), ('spouse_and_self_name', 'Nazgul__0')]), 1), (frozenset([('child_name', 'Hippogriff__((134)34)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__4')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('animal_name', 'Hippogriff__3'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__3'), ('child_name', 'Dragon__((024)34)'), ('spouse_and_self_name', 'Dragon__4')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('child_name', 'Dragon__((024)34)'), ('spouse_and_self_name', 'Dragon__4')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__(024)'), ('child_name', 'Dragon__(((024)12)(024)3)')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__(024)'), ('spouse_and_self_name', 'Nazgul__3'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('animal_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__(013)'), ('spouse_and_self_name', 'Nazgul__1')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_and_self_name', 'Dragon__(((((024)34)04)02)23)'), ('child_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('animal_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)')]), 1), (frozenset([('animal_name', 'Nazgul__(234)'), ('spouse_and_self_name', 'Nazgul__3'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)23)'), ('animal_name', 'Pteranodon__2'), ('spouse_and_self_name', 'Pteranodon__2'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Pteranodon'), ('spouse_and_self_name', 'Pteranodon__2'), ('animal_name', 'Pteranodon__0'), ('child_name', 'Pteranodon__((034)02)')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('spouse_and_self_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_and_self_name', 'Pteranodon__1'), ('spouse_species', 'Pteranodon'), ('child_name', 'Pteranodon__((((034)02)13)13)')]), 1), (frozenset([('animal_name', 'Nazgul__(013)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)24)'), ('spouse_and_self_name', 'Nazgul__(013)')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)23)'), ('spouse_and_self_name', 'Pteranodon__2'), ('animal_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('spouse_and_self_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__(((((024)34)04)02)23)')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((134)34)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__((134)14)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('animal_name', 'Hippogriff__3'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Pteranodon__((034)04)'), ('spouse_and_self_name', 'Pteranodon__((034)02)'), ('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__(((234)34)01)'), ('spouse_and_self_name', 'Nazgul__1')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((((234)34)01)24)'), ('animal_name', 'Nazgul__4'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__1'), ('animal_name', 'Hippogriff__1'), ('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__(134)')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(((034)02)23)'), ('spouse_and_self_name', 'Pteranodon__3'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((((234)34)01)24)'), ('spouse_and_self_name', 'Nazgul__4'), ('animal_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('animal_name', 'Dragon__0'), ('child_name', 'Dragon__(024)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__4')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__((034)04)'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__(024)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__3'), ('child_name', 'Dragon__((024)34)')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((024)34)'), ('spouse_and_self_name', 'Dragon__((024)34)'), ('child_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__3'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3'), ('child_name', 'Hippogriff__(134)')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)13)'), ('animal_name', 'Pteranodon__1'), ('spouse_and_self_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((024)34)'), ('spouse_and_self_name', 'Dragon__(024)'), ('child_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(((034)02)23)'), ('spouse_and_self_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)'), ('animal_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_and_self_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('animal_name', 'Pteranodon__(034)'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__(024)')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('spouse_and_self_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Pteranodon__(((034)02)23)'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Nazgul__((((234)34)01)24)')]), 1), (frozenset([('animal_name', 'Nazgul__(013)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)24)'), ('spouse_and_self_name', 'Nazgul__4')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((((234)34)01)24)'), ('spouse_and_self_name', 'Nazgul__4'), ('animal_name', 'Nazgul__4')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)13)'), ('spouse_and_self_name', 'Pteranodon__3'), ('animal_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__((013)(234)0)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__(013)')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)24)'), ('animal_name', 'Nazgul__4'), ('spouse_and_self_name', 'Nazgul__(013)')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__0'), ('spouse_and_self_name', 'Nazgul__3'), ('child_name', 'Nazgul__(013)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('animal_name', 'Hippogriff__((((134)14)02)34)'), ('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_and_self_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__0'), ('child_name', 'Nazgul__(013)'), ('animal_name', 'Nazgul__3'), ('spouse_species', 'Nazgul')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__(((234)34)01)'), ('spouse_and_self_name', 'Nazgul__0')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)13)'), ('spouse_and_self_name', 'Pteranodon__((034)02)'), ('animal_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Dragon'), ('child_name', 'Dragon__(((024)12)(024)3)'), ('spouse_and_self_name', 'Dragon__(024)'), ('animal_name', 'Dragon__((024)12)')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)23)'), ('spouse_and_self_name', 'Pteranodon__3'), ('animal_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__4'), ('animal_name', 'Hippogriff__1'), ('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__3'), ('child_name', 'Dragon__(((((024)34)04)02)23)')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)'), ('spouse_and_self_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(((034)02)13)'), ('spouse_and_self_name', 'Pteranodon__1'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__1'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((((234)34)01)24)'), ('spouse_and_self_name', 'Nazgul__(((234)34)01)'), ('animal_name', 'Nazgul__4')]), 1), (frozenset([('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)'), ('animal_name', 'Hippogriff__4'), ('spouse_and_self_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(013)'), ('spouse_and_self_name', 'Nazgul__3'), ('animal_name', 'Nazgul__1')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('child_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__(((134)14)02)'), ('animal_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__((((134)14)02)34)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_species', 'Pteranodon'), ('spouse_and_self_name', 'Pteranodon__(((034)02)13)'), ('child_name', 'Pteranodon__((((034)02)13)13)'), ('animal_name', 'Pteranodon__(((034)02)13)')]), 1), (frozenset([('spouse_species', 'Dragon'), ('child_name', 'Dragon__((((024)34)04)02)'), ('spouse_and_self_name', 'Dragon__(((024)34)04)'), ('animal_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('spouse_and_self_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('child_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_and_self_name', 'Dragon__(024)'), ('child_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__(024)'), ('spouse_and_self_name', 'Nazgul__(024)'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('spouse_species', 'Dragon'), ('child_name', 'Dragon__((024)34)'), ('spouse_and_self_name', 'Dragon__4'), ('animal_name', 'Dragon__4')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((((024)34)04)02)'), ('child_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('child_name', 'Pteranodon__((034)04)'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('animal_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Dragon__(((((024)34)04)02)((024)34)0)'), ('animal_name', 'Dragon__0'), ('spouse_and_self_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__((134)14)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('animal_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__(((024)12)(024)3)'), ('animal_name', 'Dragon__((024)12)')]), 1), (frozenset([('animal_name', 'Hippogriff__2'), ('spouse_and_self_name', 'Hippogriff__2'), ('child_name', 'Hippogriff__(024)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__3'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('animal_name', 'Hippogriff__3'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)23)'), ('animal_name', 'Pteranodon__2'), ('spouse_and_self_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__0'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__1'), ('child_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('child_name', 'Dragon__(((((024)34)04)02)((024)34)0)'), ('spouse_and_self_name', 'Dragon__0'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((024)34)')]), 1), (frozenset([('child_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))'), ('spouse_and_self_name', 'Nazgul__((013)(234)0)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__(024)')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__(034)'), ('spouse_and_self_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(024)'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('spouse_species', 'Pteranodon'), ('spouse_and_self_name', 'Pteranodon__1'), ('child_name', 'Pteranodon__((((034)02)13)13)'), ('animal_name', 'Pteranodon__(((034)02)13)')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__3'), ('spouse_and_self_name', 'Nazgul__3')]), 1), (frozenset([('animal_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__((((134)14)02)34)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__3')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('child_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__1')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_and_self_name', 'Pteranodon__((034)04)'), ('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__(024)'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__((024)34)'), ('animal_name', 'Dragon__4')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((((234)34)01)24)'), ('spouse_and_self_name', 'Nazgul__(((234)34)01)'), ('animal_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('spouse_species', 'Pteranodon'), ('animal_name', 'Pteranodon__(034)'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((034)04)')]), 1), (frozenset([('child_name', 'Hippogriff__((((134)14)02)34)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3'), ('spouse_and_self_name', 'Hippogriff__3')]), 1), (frozenset([('animal_name', 'Nazgul__(234)'), ('spouse_and_self_name', 'Nazgul__3'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('animal_name', 'Hippogriff__2'), ('child_name', 'Hippogriff__(((134)14)02)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Hippogriff__2'), ('child_name', 'Hippogriff__(((134)14)02)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__((134)14)')]), 1), (frozenset([('child_name', 'Pteranodon__(034)'), ('animal_name', 'Pteranodon__0'), ('spouse_and_self_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__(013)'), ('spouse_and_self_name', 'Nazgul__0')]), 1), (frozenset([('animal_name', 'Nazgul__((013)24)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Nazgul__(234)'), ('spouse_and_self_name', 'Nazgul__(024)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)'), ('animal_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__3'), ('child_name', 'Dragon__(((024)12)(024)3)')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__(234)'), ('animal_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('animal_name', 'Nazgul__((234)34)'), ('spouse_and_self_name', 'Nazgul__0'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__3'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('child_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__3'), ('animal_name', 'Nazgul__4')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_species', 'Pteranodon'), ('spouse_and_self_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__((((034)02)13)13)')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('spouse_and_self_name', 'Nazgul__0'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(024)')]), 1), (frozenset([('child_name', 'Nazgul__(013)'), ('animal_name', 'Nazgul__3'), ('spouse_and_self_name', 'Nazgul__3'), ('spouse_species', 'Nazgul')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__(((034)02)13)'), ('animal_name', 'Pteranodon__1'), ('spouse_species', 'Pteranodon'), ('child_name', 'Pteranodon__((((034)02)13)13)')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)13)'), ('spouse_and_self_name', 'Pteranodon__1'), ('animal_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__(024)'), ('animal_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('spouse_species', 'Pteranodon'), ('child_name', 'Pteranodon__((((034)02)13)13)'), ('spouse_and_self_name', 'Pteranodon__3'), ('animal_name', 'Pteranodon__(((034)02)13)')]), 1), (frozenset([('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('spouse_species', 'Pteranodon'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('animal_name', 'Pteranodon__(((034)02)13)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('animal_name', 'Hippogriff__2'), ('child_name', 'Hippogriff__(024)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(((034)02)13)'), ('spouse_and_self_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__1'), ('animal_name', 'Pteranodon__1'), ('spouse_species', 'Pteranodon'), ('child_name', 'Pteranodon__((((034)02)13)13)')]), 1), (frozenset([('animal_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__3'), ('child_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_species', 'Dragon'), ('child_name', 'Dragon__(024)'), ('animal_name', 'Dragon__4'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__(234)'), ('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__((013)(234)0)'), ('spouse_species', 'Nazgul')]), 1), (frozenset([('child_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)'), ('animal_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('animal_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(024)'), ('spouse_and_self_name', 'Nazgul__4')]), 1), (frozenset([('animal_name', 'Hippogriff__(((134)14)02)'), ('spouse_and_self_name', 'Hippogriff__(((134)14)02)'), ('child_name', 'Hippogriff__((((134)14)02)34)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Hippogriff__(024)')]), 1), (frozenset([('child_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)'), ('animal_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_and_self_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)24)'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('spouse_and_self_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('child_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__3'), ('spouse_and_self_name', 'Dragon__3'), ('child_name', 'Dragon__(((024)12)(024)3)')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__((234)34)'), ('animal_name', 'Nazgul__1'), ('child_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__(234)'), ('animal_name', 'Nazgul__(234)'), ('child_name', 'Nazgul__((013)(234)0)'), ('spouse_species', 'Nazgul')]), 1), (frozenset([('child_name', 'Hippogriff__((134)34)'), ('spouse_and_self_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__(134)'), ('animal_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)24)'), ('animal_name', 'Nazgul__4'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__3'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('animal_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Hippogriff__(((134)14)02)'), ('spouse_and_self_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__((((134)14)02)34)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((134)34)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__3')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__(((134)14)02)'), ('child_name', 'Hippogriff__((((134)14)02)34)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)13)'), ('spouse_and_self_name', 'Pteranodon__1'), ('animal_name', 'Pteranodon__1'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Dragon__(((((024)34)04)02)((024)34)0)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((((024)34)04)02)'), ('spouse_and_self_name', 'Dragon__((((024)34)04)02)')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((134)03)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__0')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('animal_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__3'), ('spouse_and_self_name', 'Nazgul__4'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__((034)04)'), ('animal_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Pteranodon__2'), ('child_name', 'Pteranodon__((034)02)'), ('spouse_and_self_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(034)'), ('animal_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__(((034)02)13)'), ('animal_name', 'Pteranodon__(((034)02)23)'), ('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_and_self_name', 'Dragon__((024)34)'), ('child_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('animal_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Pteranodon__1'), ('spouse_species', 'Pteranodon'), ('spouse_and_self_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__((((034)02)13)13)')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__3'), ('spouse_and_self_name', 'Dragon__(024)'), ('child_name', 'Dragon__(((024)12)(024)3)')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('spouse_and_self_name', 'Dragon__0'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__((((024)34)04)02)')]), 1), (frozenset([('spouse_species', 'Dragon'), ('child_name', 'Dragon__(((024)12)(024)3)'), ('spouse_and_self_name', 'Dragon__3'), ('animal_name', 'Dragon__((024)12)')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__((034)04)'), ('spouse_and_self_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Hippogriff__(((134)14)02)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__((134)14)'), ('spouse_and_self_name', 'Hippogriff__((134)14)')]), 1), (frozenset([('animal_name', 'Hippogriff__2'), ('spouse_and_self_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__(024)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Nazgul__((234)34)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(((234)34)01)'), ('spouse_and_self_name', 'Nazgul__((234)34)')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__0'), ('animal_name', 'Dragon__0'), ('child_name', 'Dragon__(024)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_and_self_name', 'Pteranodon__((034)02)'), ('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__(024)'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)'), ('animal_name', 'Hippogriff__4'), ('spouse_and_self_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__(((((024)34)04)02)23)'), ('child_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)'), ('spouse_and_self_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('child_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('child_name', 'Pteranodon__((034)04)'), ('animal_name', 'Pteranodon__0'), ('spouse_and_self_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__1')]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('spouse_and_self_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(013)'), ('animal_name', 'Nazgul__1'), ('spouse_and_self_name', 'Nazgul__1')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('spouse_and_self_name', 'Hippogriff__((((134)14)02)34)'), ('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__((((134)14)02)34)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3')]), 1), (frozenset([('animal_name', 'Hippogriff__((134)03)')]), 1), (frozenset([('spouse_species', 'Dragon'), ('child_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__4'), ('animal_name', 'Dragon__4')]), 1), (frozenset([('child_name', 'Nazgul__(013)'), ('animal_name', 'Nazgul__3'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__1')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('child_name', 'Hippogriff__(((134)14)02)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__(024)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__4')]), 1), (frozenset([('spouse_and_self_name', 'Nazgul__0'), ('animal_name', 'Nazgul__0'), ('child_name', 'Nazgul__(024)'), ('spouse_species', 'Nazgul')]), 1), (frozenset([('animal_name', 'Pteranodon__2'), ('spouse_and_self_name', 'Pteranodon__2'), ('child_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('child_name', 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_and_self_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__0'), ('animal_name', 'Dragon__0'), ('child_name', 'Dragon__((((024)34)04)02)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('spouse_and_self_name', 'Hippogriff__0'), ('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)23)'), ('animal_name', 'Pteranodon__2'), ('spouse_and_self_name', 'Pteranodon__3'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Nazgul__(234)'), ('child_name', 'Nazgul__((013)(234)0)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__(013)')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('spouse_and_self_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__((034)04)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__1'), ('animal_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__(024)'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__((134)34)'), ('spouse_and_self_name', 'Hippogriff__3')]), 1), (frozenset([('child_name', 'Hippogriff__(((134)14)02)'), ('spouse_and_self_name', 'Hippogriff__2'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__((134)14)')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)24)'), ('animal_name', 'Nazgul__4'), ('spouse_and_self_name', 'Nazgul__4')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('spouse_and_self_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Hippogriff__((134)03)'), ('spouse_and_self_name', 'Hippogriff__3'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('child_name', 'Dragon__(((((024)34)04)02)((024)34)0)'), ('spouse_and_self_name', 'Dragon__0'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((((024)34)04)02)')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__4'), ('animal_name', 'Nazgul__4'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__3'), ('spouse_and_self_name', 'Nazgul__3'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('child_name', 'Nazgul__(((013)(234)0)((024)(234)3)(024))'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__(024)'), ('spouse_and_self_name', 'Nazgul__(024)')]), 1), (frozenset([('animal_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__4'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__0'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__(((024)34)04)'), ('animal_name', 'Dragon__4')]), 1), (frozenset([('child_name', 'Dragon__(((((024)34)04)02)((024)34)0)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((024)34)'), ('spouse_and_self_name', 'Dragon__((024)34)')]), 1), (frozenset([('animal_name', 'Nazgul__(013)'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)24)'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__3'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__((024)34)'), ('animal_name', 'Dragon__4')]), 1), (frozenset([('child_name', 'Hippogriff__(((134)14)02)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__2'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('spouse_and_self_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_species', 'Dragon'), ('child_name', 'Dragon__((((024)34)04)02)'), ('animal_name', 'Dragon__(((024)34)04)'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('child_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__(024)')]), 1), (frozenset([('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('animal_name', 'Pteranodon__(034)'), ('spouse_and_self_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3'), ('child_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((((234)34)01)24)'), ('animal_name', 'Nazgul__(((234)34)01)'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('child_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)'), ('animal_name', 'Dragon__((((024)34)04)02)'), ('spouse_and_self_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)24)'), ('spouse_and_self_name', 'Nazgul__4')]), 1), (frozenset([('animal_name', 'Dragon__0'), ('child_name', 'Dragon__(((024)34)04)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__4')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__3'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__3'), ('child_name', 'Dragon__((024)34)')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((134)34)'), ('spouse_and_self_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('child_name', 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)'), ('animal_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_and_self_name', 'Dragon__(((((024)34)04)02)23)'), ('spouse_species', 'Dragon')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((024)34)'), ('spouse_and_self_name', 'Dragon__((024)34)'), ('child_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)'), ('animal_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('spouse_and_self_name', 'Hippogriff__4'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(034)'), ('spouse_and_self_name', 'Pteranodon__0'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Hippogriff__((134)34)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3'), ('spouse_and_self_name', 'Hippogriff__3')]), 1), (frozenset([('animal_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('child_name', 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)'), ('spouse_and_self_name', 'Hippogriff__3'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('child_name', 'Dragon__(((((024)34)04)02)((024)34)0)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((024)34)'), ('spouse_and_self_name', 'Dragon__((((024)34)04)02)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__0'), ('child_name', 'Hippogriff__((134)03)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__((034)04)'), ('animal_name', 'Pteranodon__((034)04)'), ('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((((234)34)01)24)'), ('spouse_and_self_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__(024)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('child_name', 'Dragon__((024)34)')]), 1), (frozenset([('spouse_species', 'Hippogriff'), ('child_name', 'Hippogriff__(024)'), ('spouse_and_self_name', 'Hippogriff__2'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Pteranodon__4'), ('spouse_and_self_name', 'Pteranodon__4'), ('child_name', 'Pteranodon__(034)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__((((024)34)04)02)'), ('spouse_and_self_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('child_name', 'Hippogriff__(((134)14)02)'), ('spouse_and_self_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Dragon__2'), ('spouse_species', 'Dragon'), ('child_name', 'Dragon__((((024)34)04)02)'), ('spouse_and_self_name', 'Dragon__2')]), 1), (frozenset([('spouse_and_self_name', 'Dragon__0'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__((024)34)'), ('child_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('child_name', 'Pteranodon__(((034)02)23)'), ('spouse_and_self_name', 'Pteranodon__((034)02)'), ('animal_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__((013)24)'), ('spouse_and_self_name', 'Nazgul__(013)')]), 1), (frozenset([('animal_name', 'Hippogriff__(((134)14)02)'), ('child_name', 'Hippogriff__((((134)14)02)34)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__3')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('spouse_and_self_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__(024)'), ('child_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('child_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__3'), ('spouse_and_self_name', 'Nazgul__2')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__(((034)02)13)'), ('spouse_and_self_name', 'Pteranodon__3'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('child_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('spouse_and_self_name', 'Dragon__(024)'), ('animal_name', 'Dragon__1')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__((034)04)'), ('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('animal_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('spouse_and_self_name', 'Pteranodon__(034)'), ('child_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)'), ('animal_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Nazgul__2'), ('child_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('spouse_and_self_name', 'Nazgul__3')]), 1), (frozenset([('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__(024)'), ('animal_name', 'Hippogriff__0')]), 1), (frozenset([('animal_name', 'Pteranodon__3'), ('child_name', 'Pteranodon__((((034)02)((034)04)3)(034)3)'), ('spouse_and_self_name', 'Pteranodon__(((034)02)((034)04)3)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Hippogriff__4'), ('spouse_and_self_name', 'Hippogriff__4'), ('child_name', 'Hippogriff__(024)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__(134)'), ('animal_name', 'Hippogriff__1'), ('child_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('child_name', 'Nazgul__(234)'), ('spouse_species', 'Nazgul'), ('animal_name', 'Nazgul__3'), ('spouse_and_self_name', 'Nazgul__4')]), 1), (frozenset([('animal_name', 'Pteranodon__(034)'), ('spouse_and_self_name', 'Pteranodon__2'), ('child_name', 'Pteranodon__((034)02)'), ('spouse_species', 'Pteranodon')]), 1), (frozenset([('animal_name', 'Hippogriff__(134)'), ('child_name', 'Hippogriff__((134)03)'), ('spouse_species', 'Hippogriff'), ('spouse_and_self_name', 'Hippogriff__(134)')]), 1), (frozenset([('spouse_and_self_name', 'Hippogriff__4'), ('animal_name', 'Hippogriff__1'), ('child_name', 'Hippogriff__((134)14)'), ('spouse_species', 'Hippogriff')]), 1), (frozenset([('child_name', 'Dragon__((024)12)'), ('spouse_species', 'Dragon'), ('animal_name', 'Dragon__1'), ('spouse_and_self_name', 'Dragon__1')]), 1), (frozenset([('spouse_species', 'Nazgul'), ('child_name', 'Nazgul__(013)'), ('animal_name', 'Nazgul__1'), ('spouse_and_self_name', 'Nazgul__0')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__((024)34)'), ('child_name', 'Dragon__((((((024)34)04)02)23)((024)34)(024))')]), 1), (frozenset([('spouse_species', 'Dragon'), ('animal_name', 'Dragon__(024)'), ('spouse_and_self_name', 'Dragon__3'), ('child_name', 'Dragon__(((024)12)(024)3)')]), 1), (frozenset([('child_name', 'Hippogriff__((134)03)'), ('spouse_species', 'Hippogriff'), ('animal_name', 'Hippogriff__3'), ('spouse_and_self_name', 'Hippogriff__3')]), 1)]) + +snapshots['OrientDBMatchQueryTests::test_optional_traverse_after_mandatory_traverse 1'] = frozenset([(frozenset([('child_name', 'Pteranodon__1'), ('species_name', 'Pteranodon')]), 2), (frozenset([('child_name', 'Pteranodon__2'), ('species_name', 'Pteranodon')]), 2), (frozenset([('child_name', 'Dragon__0'), ('species_name', 'Dragon')]), 4), (frozenset([('species_name', 'Nazgul'), ('child_name', 'Nazgul__((234)34)')]), 1), (frozenset([('species_name', 'Dragon')]), 5), (frozenset([('child_name', 'Hippogriff__((((134)14)02)34)'), ('species_name', 'Hippogriff')]), 1), (frozenset([('species_name', 'Nazgul'), ('child_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('species_name', 'Nazgul'), ('child_name', 'Nazgul__(024)')]), 2), (frozenset([('child_name', 'Nazgul__0'), ('species_name', 'Nazgul')]), 4), (frozenset([('species_name', 'Dragon'), ('child_name', 'Dragon__4')]), 3), (frozenset([('species_name', 'Dragon'), ('child_name', 'Dragon__((((024)34)04)02)')]), 3), (frozenset([('child_name', 'Pteranodon__0'), ('species_name', 'Pteranodon')]), 3), (frozenset([('species_name', 'Pteranodon')]), 5), (frozenset([('species_name', 'Dragon'), ('child_name', 'Dragon__((024)34)')]), 3), (frozenset([('child_name', 'Hippogriff__((134)14)'), ('species_name', 'Hippogriff')]), 2), (frozenset([('child_name', 'Pteranodon__(((034)02)23)'), ('species_name', 'Pteranodon')]), 1), (frozenset([('child_name', 'Pteranodon__((034)04)'), ('species_name', 'Pteranodon')]), 1), (frozenset([('species_name', 'Nazgul'), ('child_name', 'Nazgul__1')]), 2), (frozenset([('species_name', 'Dragon'), ('child_name', 'Dragon__3')]), 3), (frozenset([('species_name', 'Nazgul'), ('child_name', 'Nazgul__3')]), 4), (frozenset([('child_name', 'Hippogriff__0'), ('species_name', 'Hippogriff')]), 4), (frozenset([('species_name', 'Nazgul'), ('child_name', 'Nazgul__4')]), 5), (frozenset([('child_name', 'Nazgul__(013)'), ('species_name', 'Nazgul')]), 2), (frozenset([('child_name', 'Dragon__((024)12)'), ('species_name', 'Dragon')]), 1), (frozenset([('child_name', 'Hippogriff__(((((134)14)02)34)(134)0)'), ('species_name', 'Hippogriff')]), 2), (frozenset([('child_name', 'Pteranodon__4'), ('species_name', 'Pteranodon')]), 3), (frozenset([('child_name', 'Pteranodon__(((034)02)((034)04)3)'), ('species_name', 'Pteranodon')]), 1), (frozenset([('species_name', 'Hippogriff'), ('child_name', 'Hippogriff__(134)')]), 5), (frozenset([('species_name', 'Nazgul'), ('child_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('species_name', 'Hippogriff')]), 5), (frozenset([('species_name', 'Dragon'), ('child_name', 'Dragon__2')]), 5), (frozenset([('species_name', 'Dragon'), ('child_name', 'Dragon__(024)')]), 4), (frozenset([('child_name', 'Hippogriff__(((134)14)02)'), ('species_name', 'Hippogriff')]), 1), (frozenset([('child_name', 'Pteranodon__(034)'), ('species_name', 'Pteranodon')]), 5), (frozenset([('child_name', 'Hippogriff__3'), ('species_name', 'Hippogriff')]), 5), (frozenset([('species_name', 'Pteranodon'), ('child_name', 'Pteranodon__3')]), 6), (frozenset([('child_name', 'Pteranodon__(((034)02)13)'), ('species_name', 'Pteranodon')]), 2), (frozenset([('species_name', 'Dragon'), ('child_name', 'Dragon__(((((024)34)04)02)23)')]), 2), (frozenset([('child_name', 'Pteranodon__((034)02)'), ('species_name', 'Pteranodon')]), 3), (frozenset([('species_name', 'Nazgul')]), 5), (frozenset([('child_name', 'Hippogriff__1'), ('species_name', 'Hippogriff')]), 2), (frozenset([('species_name', 'Nazgul'), ('child_name', 'Nazgul__((013)(234)0)')]), 1), (frozenset([('species_name', 'Nazgul'), ('child_name', 'Nazgul__2')]), 4), (frozenset([('child_name', 'Nazgul__(234)'), ('species_name', 'Nazgul')]), 3), (frozenset([('species_name', 'Dragon'), ('child_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('child_name', 'Hippogriff__4'), ('species_name', 'Hippogriff')]), 6), (frozenset([('child_name', 'Hippogriff__2'), ('species_name', 'Hippogriff')]), 2), (frozenset([('species_name', 'Dragon'), ('child_name', 'Dragon__1')]), 1), (frozenset([('child_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))'), ('species_name', 'Pteranodon')]), 1)]) + +snapshots['OrientDBMatchQueryTests::test_traverse_and_output 1'] = frozenset([(frozenset([('parent_name', 'Nazgul__2')]), 4), (frozenset([('parent_name', 'Dragon__4')]), 3), (frozenset([('parent_name', 'Nazgul__((024)(234)3)')]), 1), (frozenset([('parent_name', 'Pteranodon__0')]), 3), (frozenset([('parent_name', 'Pteranodon__((034)04)')]), 1), (frozenset([('parent_name', 'Hippogriff__1')]), 2), (frozenset([('parent_name', 'Pteranodon__((((034)02)13)(((034)02)23)(034))')]), 1), (frozenset([('parent_name', 'Pteranodon__((034)02)')]), 3), (frozenset([('parent_name', 'Pteranodon__(((034)02)23)')]), 1), (frozenset([('parent_name', 'Nazgul__((013)(234)0)')]), 1), (frozenset([('parent_name', 'Dragon__((024)34)')]), 3), (frozenset([('parent_name', 'Pteranodon__2')]), 2), (frozenset([('parent_name', 'Pteranodon__(034)')]), 5), (frozenset([('parent_name', 'Nazgul__(013)')]), 2), (frozenset([('parent_name', 'Nazgul__(((234)34)01)')]), 1), (frozenset([('parent_name', 'Hippogriff__2')]), 2), (frozenset([('parent_name', 'Pteranodon__(((034)02)13)')]), 2), (frozenset([('parent_name', 'Hippogriff__((134)14)')]), 2), (frozenset([('parent_name', 'Nazgul__(234)')]), 3), (frozenset([('parent_name', 'Hippogriff__4')]), 6), (frozenset([('parent_name', 'Nazgul__((234)34)')]), 1), (frozenset([('parent_name', 'Hippogriff__((((134)14)02)34)')]), 1), (frozenset([('parent_name', 'Nazgul__(024)')]), 2), (frozenset([('parent_name', 'Hippogriff__0')]), 4), (frozenset([('parent_name', 'Pteranodon__3')]), 6), (frozenset([('parent_name', 'Nazgul__1')]), 2), (frozenset([('parent_name', 'Dragon__0')]), 4), (frozenset([('parent_name', 'Hippogriff__3')]), 5), (frozenset([('parent_name', 'Dragon__3')]), 3), (frozenset([('parent_name', 'Nazgul__3')]), 4), (frozenset([('parent_name', 'Dragon__1')]), 1), (frozenset([('parent_name', 'Nazgul__4')]), 5), (frozenset([('parent_name', 'Dragon__((024)12)')]), 1), (frozenset([('parent_name', 'Pteranodon__4')]), 3), (frozenset([('parent_name', 'Dragon__(((((024)34)04)02)23)')]), 2), (frozenset([('parent_name', 'Dragon__((((024)34)04)02)')]), 3), (frozenset([('parent_name', 'Pteranodon__(((034)02)((034)04)3)')]), 1), (frozenset([('parent_name', 'Hippogriff__(134)')]), 5), (frozenset([('parent_name', 'Hippogriff__(((134)14)02)')]), 1), (frozenset([('parent_name', 'Dragon__(((024)34)04)')]), 1), (frozenset([('parent_name', 'Pteranodon__1')]), 2), (frozenset([('parent_name', 'Dragon__(024)')]), 4), (frozenset([('parent_name', 'Nazgul__0')]), 4), (frozenset([('parent_name', 'Hippogriff__(((((134)14)02)34)(134)0)')]), 2), (frozenset([('parent_name', 'Dragon__2')]), 5)]) + +snapshots['OrientDBMatchQueryTests::test_traverse_filter_and_output 1'] = frozenset([(frozenset([('parent_name', 'Nazgul__2')]), 4)]) diff --git a/graphql_compiler/tests/snapshot_tests/test_orientdb_match_query.py b/graphql_compiler/tests/snapshot_tests/test_orientdb_match_query.py new file mode 100644 index 000000000..6e3f76063 --- /dev/null +++ b/graphql_compiler/tests/snapshot_tests/test_orientdb_match_query.py @@ -0,0 +1,125 @@ +# Copyright 2018-present Kensho Technologies, LLC. +from collections import Counter + +import pytest +import six +from snapshottest import TestCase + +from .. import test_input_data +from ... import graphql_to_match +from ..test_helpers import get_schema + + +def execute_graphql(schema, test_data, client, sample_parameters): + """Compile the GraphQL query to MATCH, execute it agains the test_db, and return the results.""" + if test_data.type_equivalence_hints: + # For test convenience, we accept the type equivalence hints in string form. + # Here, we convert them to the required GraphQL types. + schema_based_type_equivalence_hints = { + schema.get_type(key): schema.get_type(value) + for key, value in six.iteritems(test_data.type_equivalence_hints) + } + else: + schema_based_type_equivalence_hints = None + + result = graphql_to_match(schema, test_data.graphql_input, sample_parameters, + type_equivalence_hints=schema_based_type_equivalence_hints) + + # We need to preprocess the results to be agnostic of the returned order. + # For this we perform the following steps + # - convert lists (returned from @fold scopes) to tuples to make them hashable + # - convert each row dict to a frozenset of its items + # - create a Counter (multi-set) of the row frozensets + # - convert the multi-set to a frozenset of its items + row_dicts = [row.oRecordData for row in client.command(result.query)] + row_dicts_using_tuples = [ + { + column_name: tuple(value) if isinstance(value, list) else value + for column_name, value in row.items() + } + for row in row_dicts + ] + row_frozensets = [frozenset(row_dict.items()) for row_dict in row_dicts_using_tuples] + rows_multiset = Counter(row_frozensets) + row_counters_frozenset = frozenset(rows_multiset.items()) + + return row_counters_frozenset + + +# The following TestCase class uses the 'graph_client' fixture +# which pylint does not recognize as a class member. +# pylint: disable=no-member + + +class OrientDBMatchQueryTests(TestCase): + + def setUp(self): + """Initialize the test schema once for all tests, and disable max diff limits.""" + self.maxDiff = None + self.schema = get_schema() + + @pytest.mark.usefixtures('graph_client') + def test_immediate_output(self): + test_data = test_input_data.immediate_output() + sample_parameters = {} + + rows = execute_graphql(self.schema, test_data, self.graph_client, sample_parameters) + + self.assertMatchSnapshot(rows) + + @pytest.mark.usefixtures('graph_client') + def test_traverse_and_output(self): + test_data = test_input_data.traverse_and_output() + sample_parameters = {} + + rows = execute_graphql(self.schema, test_data, self.graph_client, sample_parameters) + + self.assertMatchSnapshot(rows) + + @pytest.mark.usefixtures('graph_client') + def test_traverse_filter_and_output(self): + test_data = test_input_data.traverse_filter_and_output() + sample_parameters = {'wanted': 'Nazgul__2'} + + rows = execute_graphql(self.schema, test_data, self.graph_client, sample_parameters) + + self.assertMatchSnapshot(rows) + + @pytest.mark.usefixtures('graph_client') + def test_filter_in_optional_block(self): + test_data = test_input_data.filter_in_optional_block() + sample_parameters = {'name': 'Nazgul__2'} + + rows = execute_graphql(self.schema, test_data, self.graph_client, sample_parameters) + + self.assertMatchSnapshot(rows) + + @pytest.mark.usefixtures('graph_client') + def test_optional_traverse_after_mandatory_traverse(self): + test_data = test_input_data.optional_traverse_after_mandatory_traverse() + sample_parameters = {} + + rows = execute_graphql(self.schema, test_data, self.graph_client, sample_parameters) + + self.assertMatchSnapshot(rows) + + @pytest.mark.usefixtures('graph_client') + def test_optional_and_deep_traverse(self): + test_data = test_input_data.optional_and_deep_traverse() + sample_parameters = {} + + rows = execute_graphql(self.schema, test_data, self.graph_client, sample_parameters) + + self.assertMatchSnapshot(rows) + + @pytest.mark.usefixtures('graph_client') + def test_fold_on_output_variable(self): + test_data = test_input_data.fold_on_output_variable() + sample_parameters = {} + + rows = execute_graphql(self.schema, test_data, self.graph_client, sample_parameters) + + self.assertMatchSnapshot(rows) + + +# pylint: enable=no-member diff --git a/graphql_compiler/tests/test_compiler.py b/graphql_compiler/tests/test_compiler.py index 4c7dc7076..14557a9bf 100644 --- a/graphql_compiler/tests/test_compiler.py +++ b/graphql_compiler/tests/test_compiler.py @@ -501,40 +501,46 @@ def test_filter_in_optional_block(self): expected_match = ''' SELECT - if(eval("(Animal__out_Animal_FedAt___1 IS NOT null)"), - Animal__out_Animal_FedAt___1.uuid, null) AS `uuid` + Animal___1.name AS `animal_name`, + if(eval("(Animal__out_Animal_ParentOf___1 IS NOT null)"), + Animal__out_Animal_ParentOf___1.name, null) AS `parent_name`, + if(eval("(Animal__out_Animal_ParentOf___1 IS NOT null)"), + Animal__out_Animal_ParentOf___1.uuid, null) AS `uuid` FROM ( MATCH {{ class: Animal, as: Animal___1 - }}.out('Animal_FedAt') {{ + }}.out('Animal_ParentOf') {{ where: ((name = {name})), optional: true, - as: Animal__out_Animal_FedAt___1 + as: Animal__out_Animal_ParentOf___1 }} RETURN $matches ) WHERE ( ( - (Animal___1.out_Animal_FedAt IS null) + (Animal___1.out_Animal_ParentOf IS null) OR - (Animal___1.out_Animal_FedAt.size() = 0) + (Animal___1.out_Animal_ParentOf.size() = 0) ) OR - (Animal__out_Animal_FedAt___1 IS NOT null) + (Animal__out_Animal_ParentOf___1 IS NOT null) ) ''' expected_gremlin = ''' g.V('@class', 'Animal') .as('Animal___1') - .ifThenElse{it.out_Animal_FedAt == null}{null}{it.out('Animal_FedAt')} + .ifThenElse{it.out_Animal_ParentOf == null}{null}{it.out('Animal_ParentOf')} .filter{it, m -> ((it == null) || (it.name == $name))} - .as('Animal__out_Animal_FedAt___1') + .as('Animal__out_Animal_ParentOf___1') .optional('Animal___1') .as('Animal___2') .transform{it, m -> new com.orientechnologies.orient.core.record.impl.ODocument([ - uuid: ((m.Animal__out_Animal_FedAt___1 != null) ? - m.Animal__out_Animal_FedAt___1.uuid : null) + animal_name: m.Animal___1.name, + parent_name: ((m.Animal__out_Animal_ParentOf___1 != null) ? + m.Animal__out_Animal_ParentOf___1.name : null), + uuid: ((m.Animal__out_Animal_ParentOf___1 != null) ? + m.Animal__out_Animal_ParentOf___1.uuid : null) ])} ''' diff --git a/graphql_compiler/tests/test_data_tools/__init__.py b/graphql_compiler/tests/test_data_tools/__init__.py new file mode 100644 index 000000000..5bdcb1f8e --- /dev/null +++ b/graphql_compiler/tests/test_data_tools/__init__.py @@ -0,0 +1 @@ +# Copyright 2018-present Kensho Technologies, LLC. diff --git a/graphql_compiler/tests/test_data_tools/data/commands.sql b/graphql_compiler/tests/test_data_tools/data/commands.sql new file mode 100644 index 000000000..802ad19c6 --- /dev/null +++ b/graphql_compiler/tests/test_data_tools/data/commands.sql @@ -0,0 +1,248 @@ +# Auto-generated output from `generate_test_sql/__init__.py`. +# Do not edit directly! +# Generated on 2018-07-17T13:02:38.056485 from compiler version 1.6.2. + +create vertex Species set limbs = 9, name = 'Nazgul', uuid = '0a5d2f34-6baa-9455-e3e7-0682c2094cac' +create vertex Species set limbs = 10, name = 'Pteranodon', uuid = '81332876-37eb-dcd9-e87a-1613e443df78' +create vertex Species set limbs = 4, name = 'Dragon', uuid = 'cca5a5a1-9e4d-6e3c-1846-d424c17c6279' +create vertex Species set limbs = 10, name = 'Hippogriff', uuid = 'af19922a-d9b8-a714-e61a-441c12e0c8b2' +create vertex Animal set birthday = DATE("2012-03-16 00:00:00"), color = 'green', name = 'Nazgul__0', net_worth = 442.69, uuid = '5a921187-19c7-8df4-8f4f-f31e78de5857' +create vertex Animal set birthday = DATE("2006-09-20 00:00:00"), color = 'orange', name = 'Nazgul__1', net_worth = 62.98, uuid = '9ca5499d-004a-e545-a011-6be5ab0c1681' +create vertex Animal set birthday = DATE("2018-11-28 00:00:00"), color = 'red', name = 'Nazgul__2', net_worth = 489.28, uuid = '8b0163c1-cd9d-2b7d-247a-8333f7b0b7d2' +create vertex Animal set birthday = DATE("2015-07-27 00:00:00"), color = 'magenta', name = 'Nazgul__3', net_worth = 603.18, uuid = 'b4e1357d-4a84-eb03-8d1f-d9b74d2b9deb' +create vertex Animal set birthday = DATE("2003-03-18 00:00:00"), color = 'green', name = 'Nazgul__4', net_worth = 656.65, uuid = '935ddd72-5129-fb7c-6288-e1a5cc457821' +create vertex Animal set birthday = DATE("2017-08-27 00:00:00"), color = 'orange', name = 'Nazgul__(024)', net_worth = 579.69, uuid = 'cfc6e625-8594-0927-468f-f53d864a7a50' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(024)') to (select from Animal where name = 'Nazgul__0') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(024)') to (select from Animal where name = 'Nazgul__2') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(024)') to (select from Animal where name = 'Nazgul__4') +create vertex Animal set birthday = DATE("2002-08-10 00:00:00"), color = 'green', name = 'Nazgul__(234)', net_worth = 190.37, uuid = '5b7c709a-cb17-5a5a-fb82-860deabca8d0' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(234)') to (select from Animal where name = 'Nazgul__2') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(234)') to (select from Animal where name = 'Nazgul__3') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(234)') to (select from Animal where name = 'Nazgul__4') +create vertex Animal set birthday = DATE("2001-02-20 00:00:00"), color = 'orange', name = 'Nazgul__(013)', net_worth = 45.23, uuid = '552116dd-2ba4-b180-cb69-ca385f3f5638' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(013)') to (select from Animal where name = 'Nazgul__0') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(013)') to (select from Animal where name = 'Nazgul__1') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(013)') to (select from Animal where name = 'Nazgul__3') +create vertex Animal set birthday = DATE("2007-12-02 00:00:00"), color = 'yellow', name = 'Nazgul__((234)34)', net_worth = 21.63, uuid = '9371a71f-d480-865f-9b38-fe803042e325' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((234)34)') to (select from Animal where name = 'Nazgul__(234)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((234)34)') to (select from Animal where name = 'Nazgul__3') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((234)34)') to (select from Animal where name = 'Nazgul__4') +create vertex Animal set birthday = DATE("2005-06-02 00:00:00"), color = 'red', name = 'Nazgul__(((234)34)01)', net_worth = 467.13, uuid = '11ebcd49-428a-1c22-d5fd-b76a19fbeb1d' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(((234)34)01)') to (select from Animal where name = 'Nazgul__((234)34)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(((234)34)01)') to (select from Animal where name = 'Nazgul__0') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(((234)34)01)') to (select from Animal where name = 'Nazgul__1') +create vertex Animal set birthday = DATE("2017-03-19 00:00:00"), color = 'orange', name = 'Nazgul__((024)(234)3)', net_worth = 966.54, uuid = 'bb4a06cb-e786-ab37-5bca-47be429817c5' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((024)(234)3)') to (select from Animal where name = 'Nazgul__(024)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((024)(234)3)') to (select from Animal where name = 'Nazgul__(234)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((024)(234)3)') to (select from Animal where name = 'Nazgul__3') +create vertex Animal set birthday = DATE("2007-07-15 00:00:00"), color = 'yellow', name = 'Nazgul__((013)(234)0)', net_worth = 311.44, uuid = '2cc0f859-aa65-24ab-713b-7e05ebe21368' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((013)(234)0)') to (select from Animal where name = 'Nazgul__(013)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((013)(234)0)') to (select from Animal where name = 'Nazgul__(234)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((013)(234)0)') to (select from Animal where name = 'Nazgul__0') +create vertex Animal set birthday = DATE("2007-08-01 00:00:00"), color = 'yellow', name = 'Nazgul__((((234)34)01)24)', net_worth = 192.3, uuid = 'b732d46f-21e1-5094-9efe-e464da90f534' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((((234)34)01)24)') to (select from Animal where name = 'Nazgul__(((234)34)01)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((((234)34)01)24)') to (select from Animal where name = 'Nazgul__2') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((((234)34)01)24)') to (select from Animal where name = 'Nazgul__4') +create vertex Animal set birthday = DATE("2002-07-14 00:00:00"), color = 'green', name = 'Nazgul__((013)24)', net_worth = 561.4, uuid = '720299e3-2a69-acc7-0bf9-c0efb5816b74' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((013)24)') to (select from Animal where name = 'Nazgul__(013)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((013)24)') to (select from Animal where name = 'Nazgul__2') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__((013)24)') to (select from Animal where name = 'Nazgul__4') +create vertex Animal set birthday = DATE("2018-08-03 00:00:00"), color = 'blue', name = 'Nazgul__(((013)(234)0)((024)(234)3)(024))', net_worth = 725.55, uuid = 'cffa6cdd-f963-a7ef-e001-11e5d29dc5df' +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(((013)(234)0)((024)(234)3)(024))') to (select from Animal where name = 'Nazgul__((013)(234)0)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(((013)(234)0)((024)(234)3)(024))') to (select from Animal where name = 'Nazgul__((024)(234)3)') +create edge Animal_ParentOf from (select from Animal where name = 'Nazgul__(((013)(234)0)((024)(234)3)(024))') to (select from Animal where name = 'Nazgul__(024)') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__0') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__1') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__2') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__3') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__4') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__(024)') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__(234)') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__(013)') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__((234)34)') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__(((234)34)01)') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__((024)(234)3)') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__((013)(234)0)') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__((((234)34)01)24)') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__((013)24)') to (select from Species where name = 'Nazgul') +create edge Animal_OfSpecies from (select from Animal where name = 'Nazgul__(((013)(234)0)((024)(234)3)(024))') to (select from Species where name = 'Nazgul') +create vertex Animal set birthday = DATE("2000-10-15 00:00:00"), color = 'black', name = 'Pteranodon__0', net_worth = 97.78, uuid = '36a98d74-00de-59f5-50f0-fc2b6ae04d52' +create vertex Animal set birthday = DATE("2016-05-03 00:00:00"), color = 'red', name = 'Pteranodon__1', net_worth = 274.71, uuid = 'fa7ff8bf-b044-284a-47ac-f2f64d6b234f' +create vertex Animal set birthday = DATE("2012-07-27 00:00:00"), color = 'red', name = 'Pteranodon__2', net_worth = 938.43, uuid = '04c14982-d9ea-d926-4745-dd9e27896389' +create vertex Animal set birthday = DATE("2017-08-11 00:00:00"), color = 'black', name = 'Pteranodon__3', net_worth = 537.92, uuid = 'a7c5cb87-9b8b-71a1-b38a-05fbf61164ce' +create vertex Animal set birthday = DATE("2005-05-11 00:00:00"), color = 'blue', name = 'Pteranodon__4', net_worth = 93.7, uuid = '4a814d53-964d-db77-6025-f0ae35354579' +create vertex Animal set birthday = DATE("2010-04-14 00:00:00"), color = 'yellow', name = 'Pteranodon__(034)', net_worth = 239.7, uuid = '4a1eb1b7-955d-0e77-fb5e-b8662640211e' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(034)') to (select from Animal where name = 'Pteranodon__0') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(034)') to (select from Animal where name = 'Pteranodon__3') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(034)') to (select from Animal where name = 'Pteranodon__4') +create vertex Animal set birthday = DATE("2002-07-14 00:00:00"), color = 'green', name = 'Pteranodon__((034)02)', net_worth = 337.08, uuid = 'd5e73e3f-6736-17d9-4d7b-d307122411e6' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((034)02)') to (select from Animal where name = 'Pteranodon__(034)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((034)02)') to (select from Animal where name = 'Pteranodon__0') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((034)02)') to (select from Animal where name = 'Pteranodon__2') +create vertex Animal set birthday = DATE("2013-11-26 00:00:00"), color = 'green', name = 'Pteranodon__((034)04)', net_worth = 626.74, uuid = '6d316b4a-7f6b-8793-b318-ad4c1db2b452' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((034)04)') to (select from Animal where name = 'Pteranodon__(034)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((034)04)') to (select from Animal where name = 'Pteranodon__0') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((034)04)') to (select from Animal where name = 'Pteranodon__4') +create vertex Animal set birthday = DATE("2009-06-14 00:00:00"), color = 'yellow', name = 'Pteranodon__(((034)02)((034)04)3)', net_worth = 584.88, uuid = '0202861c-6283-0869-0fa7-ee0538974df5' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((034)02)((034)04)3)') to (select from Animal where name = 'Pteranodon__((034)02)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((034)02)((034)04)3)') to (select from Animal where name = 'Pteranodon__((034)04)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((034)02)((034)04)3)') to (select from Animal where name = 'Pteranodon__3') +create vertex Animal set birthday = DATE("2016-09-26 00:00:00"), color = 'red', name = 'Pteranodon__(((034)02)23)', net_worth = 451.61, uuid = '5bc7fdeb-3123-4efe-6e64-80432aa50f4e' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((034)02)23)') to (select from Animal where name = 'Pteranodon__((034)02)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((034)02)23)') to (select from Animal where name = 'Pteranodon__2') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((034)02)23)') to (select from Animal where name = 'Pteranodon__3') +create vertex Animal set birthday = DATE("2007-07-05 00:00:00"), color = 'blue', name = 'Pteranodon__(((034)02)13)', net_worth = 988.68, uuid = '25777cf0-9f98-2188-3744-da64cc249558' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((034)02)13)') to (select from Animal where name = 'Pteranodon__((034)02)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((034)02)13)') to (select from Animal where name = 'Pteranodon__1') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((034)02)13)') to (select from Animal where name = 'Pteranodon__3') +create vertex Animal set birthday = DATE("2016-11-28 00:00:00"), color = 'black', name = 'Pteranodon__((((034)02)13)13)', net_worth = 635.06, uuid = '856f3d95-e0ae-1a1b-6c59-6216ae0fdbc8' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((((034)02)13)13)') to (select from Animal where name = 'Pteranodon__(((034)02)13)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((((034)02)13)13)') to (select from Animal where name = 'Pteranodon__1') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((((034)02)13)13)') to (select from Animal where name = 'Pteranodon__3') +create vertex Animal set birthday = DATE("2016-08-05 00:00:00"), color = 'magenta', name = 'Pteranodon__((((034)02)13)(((034)02)23)(034))', net_worth = 379.0, uuid = '52631db9-d170-34ce-5179-7350e6256403' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((((034)02)13)(((034)02)23)(034))') to (select from Animal where name = 'Pteranodon__(((034)02)13)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((((034)02)13)(((034)02)23)(034))') to (select from Animal where name = 'Pteranodon__(((034)02)23)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((((034)02)13)(((034)02)23)(034))') to (select from Animal where name = 'Pteranodon__(034)') +create vertex Animal set birthday = DATE("2014-06-25 00:00:00"), color = 'green', name = 'Pteranodon__((((034)02)((034)04)3)(034)3)', net_worth = 800.64, uuid = '21681081-399f-8a8f-10fc-9eee0a1727f7' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((((034)02)((034)04)3)(034)3)') to (select from Animal where name = 'Pteranodon__(((034)02)((034)04)3)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((((034)02)((034)04)3)(034)3)') to (select from Animal where name = 'Pteranodon__(034)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__((((034)02)((034)04)3)(034)3)') to (select from Animal where name = 'Pteranodon__3') +create vertex Animal set birthday = DATE("2012-10-22 00:00:00"), color = 'magenta', name = 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)', net_worth = 990.53, uuid = '809f2923-87a1-798f-e6ad-dd9e61d9fe39' +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)') to (select from Animal where name = 'Pteranodon__((((034)02)13)(((034)02)23)(034))') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)') to (select from Animal where name = 'Pteranodon__(034)') +create edge Animal_ParentOf from (select from Animal where name = 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)') to (select from Animal where name = 'Pteranodon__4') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__0') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__1') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__2') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__3') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__4') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__(034)') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__((034)02)') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__((034)04)') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__(((034)02)((034)04)3)') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__(((034)02)23)') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__(((034)02)13)') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__((((034)02)13)13)') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__((((034)02)13)(((034)02)23)(034))') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__((((034)02)((034)04)3)(034)3)') to (select from Species where name = 'Pteranodon') +create edge Animal_OfSpecies from (select from Animal where name = 'Pteranodon__(((((034)02)13)(((034)02)23)(034))(034)4)') to (select from Species where name = 'Pteranodon') +create vertex Animal set birthday = DATE("2017-06-28 00:00:00"), color = 'green', name = 'Dragon__0', net_worth = 845.49, uuid = 'c12ea9b8-e7e1-3ed8-6d26-5dd8bf391fbb' +create vertex Animal set birthday = DATE("2015-08-01 00:00:00"), color = 'orange', name = 'Dragon__1', net_worth = 181.96, uuid = '961d8dcf-9b80-86da-6379-4035f8e45086' +create vertex Animal set birthday = DATE("2004-10-22 00:00:00"), color = 'yellow', name = 'Dragon__2', net_worth = 384.15, uuid = '552ae5ca-4124-405b-91fc-fe8881c16e98' +create vertex Animal set birthday = DATE("2009-11-21 00:00:00"), color = 'yellow', name = 'Dragon__3', net_worth = 673.54, uuid = '0932f5b6-f11d-dff7-0e37-05265582a3bd' +create vertex Animal set birthday = DATE("2008-06-03 00:00:00"), color = 'red', name = 'Dragon__4', net_worth = 778.14, uuid = '5a4f4145-fc98-c279-cf6f-111c26c06e67' +create vertex Animal set birthday = DATE("2008-08-10 00:00:00"), color = 'magenta', name = 'Dragon__(024)', net_worth = 124.32, uuid = 'e19b5837-1c6a-4b5e-7d85-9725c707aef9' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(024)') to (select from Animal where name = 'Dragon__0') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(024)') to (select from Animal where name = 'Dragon__2') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(024)') to (select from Animal where name = 'Dragon__4') +create vertex Animal set birthday = DATE("2008-10-13 00:00:00"), color = 'orange', name = 'Dragon__((024)34)', net_worth = 789.55, uuid = '306aa871-feef-71cb-c915-d113dc45488d' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((024)34)') to (select from Animal where name = 'Dragon__(024)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((024)34)') to (select from Animal where name = 'Dragon__3') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((024)34)') to (select from Animal where name = 'Dragon__4') +create vertex Animal set birthday = DATE("2002-11-12 00:00:00"), color = 'indigo', name = 'Dragon__(((024)34)04)', net_worth = 84.03, uuid = '81d1bf06-6b8c-66f2-8611-f583b2d10e3d' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((024)34)04)') to (select from Animal where name = 'Dragon__((024)34)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((024)34)04)') to (select from Animal where name = 'Dragon__0') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((024)34)04)') to (select from Animal where name = 'Dragon__4') +create vertex Animal set birthday = DATE("2016-04-08 00:00:00"), color = 'yellow', name = 'Dragon__((((024)34)04)02)', net_worth = 352.5, uuid = '6ac1ca75-afb9-18c8-6e5b-ac20725c2675' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((((024)34)04)02)') to (select from Animal where name = 'Dragon__(((024)34)04)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((((024)34)04)02)') to (select from Animal where name = 'Dragon__0') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((((024)34)04)02)') to (select from Animal where name = 'Dragon__2') +create vertex Animal set birthday = DATE("2001-11-06 00:00:00"), color = 'orange', name = 'Dragon__((024)12)', net_worth = 204.79, uuid = 'f96d4403-d48c-93f3-028d-042b2d8b5b41' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((024)12)') to (select from Animal where name = 'Dragon__(024)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((024)12)') to (select from Animal where name = 'Dragon__1') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((024)12)') to (select from Animal where name = 'Dragon__2') +create vertex Animal set birthday = DATE("2004-02-13 00:00:00"), color = 'indigo', name = 'Dragon__(((((024)34)04)02)((024)34)0)', net_worth = 476.69, uuid = 'b080e003-5e7f-503c-4b13-47f601d6d903' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((((024)34)04)02)((024)34)0)') to (select from Animal where name = 'Dragon__((((024)34)04)02)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((((024)34)04)02)((024)34)0)') to (select from Animal where name = 'Dragon__((024)34)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((((024)34)04)02)((024)34)0)') to (select from Animal where name = 'Dragon__0') +create vertex Animal set birthday = DATE("2017-12-23 00:00:00"), color = 'blue', name = 'Dragon__(((((024)34)04)02)23)', net_worth = 315.89, uuid = '94b28b9d-8881-9f42-1a42-b62914afe646' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((((024)34)04)02)23)') to (select from Animal where name = 'Dragon__((((024)34)04)02)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((((024)34)04)02)23)') to (select from Animal where name = 'Dragon__2') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((((024)34)04)02)23)') to (select from Animal where name = 'Dragon__3') +create vertex Animal set birthday = DATE("2007-09-04 00:00:00"), color = 'magenta', name = 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)', net_worth = 299.38, uuid = 'dc68d4fd-0bd7-696f-a9c7-2e7b6b770df1' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)') to (select from Animal where name = 'Dragon__(((((024)34)04)02)23)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)') to (select from Animal where name = 'Dragon__((((024)34)04)02)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)') to (select from Animal where name = 'Dragon__2') +create vertex Animal set birthday = DATE("2007-12-02 00:00:00"), color = 'yellow', name = 'Dragon__((((((024)34)04)02)23)((024)34)(024))', net_worth = 408.62, uuid = '15a5712c-5ac4-b6c7-a310-34dd4c4b91fe' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((((((024)34)04)02)23)((024)34)(024))') to (select from Animal where name = 'Dragon__(((((024)34)04)02)23)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((((((024)34)04)02)23)((024)34)(024))') to (select from Animal where name = 'Dragon__((024)34)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__((((((024)34)04)02)23)((024)34)(024))') to (select from Animal where name = 'Dragon__(024)') +create vertex Animal set birthday = DATE("2003-02-04 00:00:00"), color = 'red', name = 'Dragon__(((024)12)(024)3)', net_worth = 605.54, uuid = 'f3cc9d8a-4b16-78e4-5f20-f4063438b4e4' +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((024)12)(024)3)') to (select from Animal where name = 'Dragon__((024)12)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((024)12)(024)3)') to (select from Animal where name = 'Dragon__(024)') +create edge Animal_ParentOf from (select from Animal where name = 'Dragon__(((024)12)(024)3)') to (select from Animal where name = 'Dragon__3') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__0') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__1') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__2') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__3') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__4') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__(024)') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__((024)34)') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__(((024)34)04)') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__((((024)34)04)02)') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__((024)12)') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__(((((024)34)04)02)((024)34)0)') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__(((((024)34)04)02)23)') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__((((((024)34)04)02)23)((((024)34)04)02)2)') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__((((((024)34)04)02)23)((024)34)(024))') to (select from Species where name = 'Dragon') +create edge Animal_OfSpecies from (select from Animal where name = 'Dragon__(((024)12)(024)3)') to (select from Species where name = 'Dragon') +create vertex Animal set birthday = DATE("2018-05-15 00:00:00"), color = 'blue', name = 'Hippogriff__0', net_worth = 355.36, uuid = '6bf4d047-c484-1a8d-2f75-1bde66163e5b' +create vertex Animal set birthday = DATE("2014-08-16 00:00:00"), color = 'green', name = 'Hippogriff__1', net_worth = 156.22, uuid = '01fda698-7646-57ca-9e65-736c72f774b1' +create vertex Animal set birthday = DATE("2004-04-22 00:00:00"), color = 'red', name = 'Hippogriff__2', net_worth = 908.77, uuid = '656fa7e6-b5c0-3f6f-94e4-cc44e3fbdbda' +create vertex Animal set birthday = DATE("2004-12-05 00:00:00"), color = 'magenta', name = 'Hippogriff__3', net_worth = 414.83, uuid = '57030ede-889c-8ae2-4e3c-0f2d4332559d' +create vertex Animal set birthday = DATE("2012-05-22 00:00:00"), color = 'yellow', name = 'Hippogriff__4', net_worth = 788.17, uuid = '88083ebc-35d4-cd35-a08c-3a0085e74250' +create vertex Animal set birthday = DATE("2008-07-09 00:00:00"), color = 'yellow', name = 'Hippogriff__(134)', net_worth = 632.11, uuid = '1eda4209-b270-af55-1f90-78d52835bcdb' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(134)') to (select from Animal where name = 'Hippogriff__1') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(134)') to (select from Animal where name = 'Hippogriff__3') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(134)') to (select from Animal where name = 'Hippogriff__4') +create vertex Animal set birthday = DATE("2008-11-01 00:00:00"), color = 'red', name = 'Hippogriff__((134)14)', net_worth = 526.82, uuid = '9f032cdc-e328-66d3-0d6a-78b07eda9ab9' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((134)14)') to (select from Animal where name = 'Hippogriff__(134)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((134)14)') to (select from Animal where name = 'Hippogriff__1') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((134)14)') to (select from Animal where name = 'Hippogriff__4') +create vertex Animal set birthday = DATE("2002-01-08 00:00:00"), color = 'green', name = 'Hippogriff__((134)03)', net_worth = 640.37, uuid = '65264961-ab44-14ae-ecb3-d561bdf0b015' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((134)03)') to (select from Animal where name = 'Hippogriff__(134)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((134)03)') to (select from Animal where name = 'Hippogriff__0') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((134)03)') to (select from Animal where name = 'Hippogriff__3') +create vertex Animal set birthday = DATE("2006-03-12 00:00:00"), color = 'yellow', name = 'Hippogriff__(((134)14)02)', net_worth = 897.2, uuid = '1aff71ae-30f2-c485-49b5-64fb92a651d7' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(((134)14)02)') to (select from Animal where name = 'Hippogriff__((134)14)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(((134)14)02)') to (select from Animal where name = 'Hippogriff__0') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(((134)14)02)') to (select from Animal where name = 'Hippogriff__2') +create vertex Animal set birthday = DATE("2015-06-06 00:00:00"), color = 'black', name = 'Hippogriff__((((134)14)02)34)', net_worth = 709.99, uuid = '7df0fe6b-ce8d-75f2-6d62-e40c638d521a' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((((134)14)02)34)') to (select from Animal where name = 'Hippogriff__(((134)14)02)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((((134)14)02)34)') to (select from Animal where name = 'Hippogriff__3') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((((134)14)02)34)') to (select from Animal where name = 'Hippogriff__4') +create vertex Animal set birthday = DATE("2009-12-27 00:00:00"), color = 'black', name = 'Hippogriff__(((((134)14)02)34)(134)0)', net_worth = 929.75, uuid = '7552c6e8-6953-a115-5a62-ddc4e2091f49' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(((((134)14)02)34)(134)0)') to (select from Animal where name = 'Hippogriff__((((134)14)02)34)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(((((134)14)02)34)(134)0)') to (select from Animal where name = 'Hippogriff__(134)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(((((134)14)02)34)(134)0)') to (select from Animal where name = 'Hippogriff__0') +create vertex Animal set birthday = DATE("2000-05-09 00:00:00"), color = 'red', name = 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)', net_worth = 7.13, uuid = '56525ce0-3725-bd0c-79c4-5c38b440ffe0' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)') to (select from Animal where name = 'Hippogriff__(((((134)14)02)34)(134)0)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)') to (select from Animal where name = 'Hippogriff__(134)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)') to (select from Animal where name = 'Hippogriff__4') +create vertex Animal set birthday = DATE("2006-02-25 00:00:00"), color = 'yellow', name = 'Hippogriff__(024)', net_worth = 794.79, uuid = 'ebe0572c-8ec9-ea98-6581-f9349bcfb1c4' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(024)') to (select from Animal where name = 'Hippogriff__0') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(024)') to (select from Animal where name = 'Hippogriff__2') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__(024)') to (select from Animal where name = 'Hippogriff__4') +create vertex Animal set birthday = DATE("2016-05-24 00:00:00"), color = 'red', name = 'Hippogriff__((134)34)', net_worth = 251.27, uuid = '30ac79dd-0b5a-afef-85a1-282a0761585b' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((134)34)') to (select from Animal where name = 'Hippogriff__(134)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((134)34)') to (select from Animal where name = 'Hippogriff__3') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((134)34)') to (select from Animal where name = 'Hippogriff__4') +create vertex Animal set birthday = DATE("2000-10-28 00:00:00"), color = 'black', name = 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)', net_worth = 460.51, uuid = '75ff93f0-025b-7c5f-1284-b9d78d4e2753' +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)') to (select from Animal where name = 'Hippogriff__(((((134)14)02)34)(134)0)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)') to (select from Animal where name = 'Hippogriff__((134)14)') +create edge Animal_ParentOf from (select from Animal where name = 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)') to (select from Animal where name = 'Hippogriff__3') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__0') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__1') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__2') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__3') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__4') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__(134)') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__((134)14)') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__((134)03)') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__(((134)14)02)') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__((((134)14)02)34)') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__(((((134)14)02)34)(134)0)') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__((((((134)14)02)34)(134)0)(134)4)') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__(024)') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__((134)34)') to (select from Species where name = 'Hippogriff') +create edge Animal_OfSpecies from (select from Animal where name = 'Hippogriff__((((((134)14)02)34)(134)0)((134)14)3)') to (select from Species where name = 'Hippogriff') diff --git a/graphql_compiler/tests/test_data_tools/data_tool.py b/graphql_compiler/tests/test_data_tools/data_tool.py new file mode 100644 index 000000000..16fbd3526 --- /dev/null +++ b/graphql_compiler/tests/test_data_tools/data_tool.py @@ -0,0 +1,18 @@ +# Copyright 2018-present Kensho Technologies, LLC. +from glob import glob +from os import path + + +def generate_data(client): + """Create test DB from the SQL commands file.""" + project_root = path.dirname(path.abspath(__file__)) + sql_files = glob(path.join(project_root, 'data/*.sql')) + for filepath in sql_files: + with open(filepath) as f: + for command in f.readlines(): + sanitized_command = command.strip() + if len(sanitized_command) == 0 or sanitized_command[0] == '#': + # comment or empty line, ignore + continue + + client.command(sanitized_command) diff --git a/graphql_compiler/tests/test_data_tools/graph.py b/graphql_compiler/tests/test_data_tools/graph.py new file mode 100644 index 000000000..f6d76864f --- /dev/null +++ b/graphql_compiler/tests/test_data_tools/graph.py @@ -0,0 +1,35 @@ +# Copyright 2018-present Kensho Technologies, LLC. +from pyorient import OrientDB +from pyorient.constants import DB_TYPE_GRAPH +from pyorient.ogm import Config, Graph + +from .data_tool import generate_data +from .schema import load_schema + + +ORIENTDB_SERVER = "localhost" +ORIENTDB_PORT = 2424 +ORIENTDB_USER = "root" +ORIENTDB_PASSWORD = "root" + + +def get_orientdb_url(database_name): + """Return an OrientDB path for the specified database on the ORIENTDB_SERVER.""" + template = 'memory://{}/{}' + return template.format(ORIENTDB_SERVER, database_name) + + +def get_test_graph(graph_name): + """Generate the test database and return the pyorient client.""" + url = get_orientdb_url(graph_name) + config = Config.from_url(url, ORIENTDB_USER, ORIENTDB_PASSWORD, initial_drop=True) + Graph(config, strict=True) + + client = OrientDB('localhost', ORIENTDB_PORT) + client.connect(ORIENTDB_USER, ORIENTDB_PASSWORD) + client.db_open(graph_name, ORIENTDB_USER, ORIENTDB_PASSWORD, db_type=DB_TYPE_GRAPH) + + load_schema(client) + generate_data(client) + + return client diff --git a/graphql_compiler/tests/test_data_tools/schema.py b/graphql_compiler/tests/test_data_tools/schema.py new file mode 100644 index 000000000..759a7183a --- /dev/null +++ b/graphql_compiler/tests/test_data_tools/schema.py @@ -0,0 +1,25 @@ +# Copyright 2018-present Kensho Technologies, LLC. +from glob import glob +from os import path + + +def load_schema(client): + """Read the schema file and apply the specified SQL updates to the client.""" + project_root = path.dirname(path.dirname(path.abspath(__file__))) + file_path = path.join(project_root, 'test_data_tools/schema.sql') + sql_files = glob(file_path) + if len(sql_files) > 1: + raise AssertionError(u'Multiple schema files found. Expected single `schema.sql` ' + u'in graphql-compiler/graphql_compiler/tests/test_data_tools/') + if len(sql_files) == 0 or sql_files[0] != file_path: + raise AssertionError(u'Schema file not found. Expected graphql-compiler/graphql_compiler/' + u'tests/test_data_tools/schema.sql') + + with open(file_path, 'r') as update_file: + for line in update_file: + sanitized = line.strip() + if len(sanitized) == 0 or sanitized[0] == '#': + # comment or empty line, ignore + continue + + client.command(sanitized) diff --git a/graphql_compiler/tests/test_data_tools/schema.sql b/graphql_compiler/tests/test_data_tools/schema.sql new file mode 100644 index 000000000..324f473a7 --- /dev/null +++ b/graphql_compiler/tests/test_data_tools/schema.sql @@ -0,0 +1,82 @@ +### UUIDs ### +CREATE CLASS UniquelyIdentifiable +CREATE PROPERTY UniquelyIdentifiable.uuid String +# make uuid default to '' and insert such a record on purpose +# this will ensure that no UniquelyIdentifiable is added without a valid uuid field +ALTER PROPERTY UniquelyIdentifiable.uuid DEFAULT '' +INSERT INTO UniquelyIdentifiable SET uuid = '' +CREATE INDEX UniquelyIdentifiable.uuid UNIQUE_HASH_INDEX +############### + +### Entity ### +CREATE CLASS Entity EXTENDS V, UniquelyIdentifiable ABSTRACT +CREATE PROPERTY Entity.name String +CREATE INDEX Entity.name UNIQUE + +CREATE PROPERTY Entity.alias EmbeddedSet String +ALTER PROPERTY Entity.alias DEFAULT {} +CREATE INDEX Entity.alias NOTUNIQUE + +CREATE PROPERTY Entity.description String +############### + +### Event ### +CREATE CLASS Event EXTENDS Entity + +CREATE PROPERTY Event.event_date Date +CREATE INDEX Event.event_date NOTUNIQUE +############### + +### BirthEvent ### +CREATE CLASS BirthEvent EXTENDS Event +############### + +### Animal ### +CREATE CLASS Animal EXTENDS Entity + +CREATE PROPERTY Animal.color String +CREATE INDEX Animal.color NOTUNIQUE + +CREATE PROPERTY Animal.birthday Date +CREATE INDEX Animal.birthday NOTUNIQUE + +CREATE PROPERTY Animal.net_worth Decimal +CREATE INDEX Animal.net_worth NOTUNIQUE + +CREATE CLASS Animal_ParentOf EXTENDS E +CREATE PROPERTY Animal_ParentOf.out LINK Animal +CREATE PROPERTY Animal_ParentOf.in LINK Animal +CREATE INDEX Animal_ParentOf ON Animal_ParentOf (in, out) UNIQUE_HASH_INDEX + +CREATE CLASS Animal_FedAt EXTENDS E +CREATE PROPERTY Animal_FedAt.in LINK Event +CREATE PROPERTY Animal_FedAt.out LINK Animal +CREATE INDEX Animal_FedAt ON Animal_FedAt (in, out) UNIQUE_HASH_INDEX + +CREATE CLASS Animal_ImportantEvent EXTENDS E +CREATE PROPERTY Animal_ImportantEvent.in LINK Event +CREATE PROPERTY Animal_ImportantEvent.out LINK Animal +CREATE INDEX Animal_ImportantEvent ON Animal_ImportantEvent (in, out) UNIQUE_HASH_INDEX + +CREATE CLASS Animal_BornAt EXTENDS E +CREATE PROPERTY Animal_BornAt.in LINK Event +CREATE PROPERTY Animal_BornAt.out LINK Animal +CREATE INDEX Animal_BornAt ON Animal_BornAt (in, out) UNIQUE_HASH_INDEX +############### + +### Species ### +CREATE CLASS Species EXTENDS Entity + +CREATE PROPERTY Species.limbs Integer +CREATE INDEX Species.limbs NOTUNIQUE + +CREATE CLASS Species_Eats EXTENDS E +CREATE PROPERTY Species_Eats.out LINK Species +CREATE PROPERTY Species_Eats.in LINK Species +CREATE INDEX Species_Eats ON Species_Eats (in, out) UNIQUE_HASH_INDEX + +CREATE CLASS Animal_OfSpecies EXTENDS E +CREATE PROPERTY Animal_OfSpecies.in LINK Species +CREATE PROPERTY Animal_OfSpecies.out LINK Animal +CREATE INDEX Animal_OfSpecies ON Animal_OfSpecies (in, out) UNIQUE_HASH_INDEX +############### diff --git a/graphql_compiler/tests/test_input_data.py b/graphql_compiler/tests/test_input_data.py index 21fd4eca9..ad23b07fc 100644 --- a/graphql_compiler/tests/test_input_data.py +++ b/graphql_compiler/tests/test_input_data.py @@ -268,13 +268,17 @@ def filter_on_optional_variable_name_or_alias(): def filter_in_optional_block(): graphql_input = '''{ Animal { - out_Animal_FedAt @optional { + name @output(out_name: "animal_name") + out_Animal_ParentOf @optional { name @filter(op_name: "=", value: ["$name"]) + @output(out_name: "parent_name") uuid @output(out_name: "uuid") } } }''' expected_output_metadata = { + 'animal_name': OutputMetadata(type=GraphQLString, optional=False), + 'parent_name': OutputMetadata(type=GraphQLString, optional=True), 'uuid': OutputMetadata(type=GraphQLID, optional=True), } expected_input_metadata = { diff --git a/graphql_compiler/tests/test_ir_generation.py b/graphql_compiler/tests/test_ir_generation.py index 307d42314..3fd7ae985 100644 --- a/graphql_compiler/tests/test_ir_generation.py +++ b/graphql_compiler/tests/test_ir_generation.py @@ -472,13 +472,13 @@ def test_filter_in_optional_block(self): test_data = test_input_data.filter_in_optional_block() base_location = helpers.Location(('Animal',)) - animal_fed_at_location = base_location.navigate_to_subpath('out_Animal_FedAt') + animal_parent_location = base_location.navigate_to_subpath('out_Animal_ParentOf') revisited_base_location = base_location.revisit() expected_blocks = [ blocks.QueryRoot({'Animal'}), blocks.MarkLocation(base_location), - blocks.Traverse('out', 'Animal_FedAt', optional=True), + blocks.Traverse('out', 'Animal_ParentOf', optional=True), blocks.Filter( expressions.BinaryComposition( u'=', @@ -486,22 +486,31 @@ def test_filter_in_optional_block(self): expressions.Variable('$name', GraphQLString) ) ), - blocks.MarkLocation(animal_fed_at_location), + blocks.MarkLocation(animal_parent_location), blocks.EndOptional(), blocks.Backtrack(base_location, optional=True), blocks.MarkLocation(revisited_base_location), blocks.ConstructResult({ + 'animal_name': expressions.OutputContextField( + base_location.navigate_to_field('name'), GraphQLString + ), + 'parent_name': expressions.TernaryConditional( + expressions.ContextFieldExistence(animal_parent_location), + expressions.OutputContextField( + animal_parent_location.navigate_to_field('name'), GraphQLString), + expressions.NullLiteral + ), 'uuid': expressions.TernaryConditional( - expressions.ContextFieldExistence(animal_fed_at_location), + expressions.ContextFieldExistence(animal_parent_location), expressions.OutputContextField( - animal_fed_at_location.navigate_to_field('uuid'), GraphQLID), + animal_parent_location.navigate_to_field('uuid'), GraphQLID), expressions.NullLiteral ) }), ] expected_location_types = { base_location: 'Animal', - animal_fed_at_location: 'Event', + animal_parent_location: 'Animal', revisited_base_location: 'Animal', } diff --git a/scripts/generate_test_sql/__init__.py b/scripts/generate_test_sql/__init__.py new file mode 100644 index 000000000..e4ae6e7c0 --- /dev/null +++ b/scripts/generate_test_sql/__init__.py @@ -0,0 +1,61 @@ +# Copyright 2018-present Kensho Technologies, LLC. +import codecs +import datetime +from os import path +import random +import re +import sys + +from .animals import get_animal_generation_commands +from .species import get_species_generation_commands + + +# https://packaging.python.org/guides/single-sourcing-package-version/ +# #single-sourcing-the-version + + +def read_file(filename): + """Read and return text from the file specified by `filename`, in the project root directory.""" + # intentionally *not* adding an encoding option to open + # see here: + # https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690 + top_level_directory = path.dirname(path.dirname(path.dirname(path.abspath(__file__)))) + with codecs.open(path.join(top_level_directory, 'graphql_compiler', filename), 'r') as f: + return f.read() + + +def find_version(): + """Return current version of package.""" + version_file = read_file('__init__.py') + version_match = re.search(r'^__version__ = ["\']([^"\']*)["\']', version_file, re.M) + if version_match: + return version_match.group(1) + raise RuntimeError('Unable to find version string.') + + +def main(): + """Print a list of SQL commands to generate the testing database.""" + random.seed(0) + + module_path = path.relpath(__file__) + current_datetime = datetime.datetime.now().isoformat() + + log_message = ('# Auto-generated output from `{path}`.\n' + '# Do not edit directly!\n' + '# Generated on {datetime} from compiler version {version}.\n\n') + + sys.stdout.write( + log_message.format(path=module_path, datetime=current_datetime, version=find_version())) + + sql_command_generators = [ + get_species_generation_commands, + get_animal_generation_commands, + ] + for sql_command_generator in sql_command_generators: + sql_command_list = sql_command_generator() + sys.stdout.write('\n'.join(sql_command_list)) + sys.stdout.write('\n') + + +if __name__ == '__main__': + main() diff --git a/scripts/generate_test_sql/animals.py b/scripts/generate_test_sql/animals.py new file mode 100644 index 000000000..8a9807090 --- /dev/null +++ b/scripts/generate_test_sql/animals.py @@ -0,0 +1,100 @@ +# Copyright 2017-present Kensho Technologies, LLC. +import random + +from .species import SPECIES_LIST +from .utils import (create_edge_statement, create_name, create_vertex_statement, + extract_base_name_and_label, get_random_date, get_random_net_worth, get_uuid) + + +NUM_INITIAL_ANIMALS = 5 +NUM_GENERATIONS = 10 +NUM_PARENTS = 3 +ANIMAL_COLOR_LIST = ( + 'red', + 'blue', + 'green', + 'yellow', + 'magenta', + 'black', + 'orange', + 'indigo', +) + + +def _create_animal_statement(animal_name): + """Return a SQL statement to create an animal vertex.""" + field_name_to_value = { + 'name': animal_name, + 'uuid': get_uuid(), + 'color': random.choice(ANIMAL_COLOR_LIST), # nosec + 'birthday': get_random_date(), + 'net_worth': get_random_net_worth(), + } + return create_vertex_statement('Animal', field_name_to_value) + + +def _create_animal_parent_of_statement(from_name, to_name): + """Return a SQL statement to create an Animal_ParentOf edge.""" + return create_edge_statement('Animal_ParentOf', 'Animal', from_name, 'Animal', to_name) + + +def _create_animal_of_species_statement(from_name, to_name): + """Return a SQL statement to create an Animal_OfSpecies edge.""" + return create_edge_statement('Animal_OfSpecies', 'Animal', from_name, 'Species', to_name) + + +def _get_initial_animal_generators(species_name, current_animal_names): + """Return a list of SQL statements to create initial animals for a given species.""" + command_list = [] + for index in range(NUM_INITIAL_ANIMALS): + animal_name = create_name(species_name, str(index)) + current_animal_names.append(animal_name) + command_list.append(_create_animal_statement(animal_name)) + return command_list + + +def _get_new_parents(current_animal_names, previous_parent_sets, num_parents): + """Return a set of `num_parents` parent names that is not present in `previous_parent_sets`.""" + while True: + new_parent_names = frozenset(random.sample(current_animal_names, num_parents)) + # Duplicating a set of parents could result in Animals with the same names. + # This would invalidate unique selection of Animals by name. + if new_parent_names not in previous_parent_sets: + return new_parent_names + + +def get_animal_generation_commands(): + """Return a list of SQL statements to create animal vertices and their corresponding edges.""" + command_list = [] + species_to_names = {} + previous_parent_sets = set() + + for species_name in SPECIES_LIST: + current_animal_names = [] + species_to_names[species_name] = current_animal_names + command_list.extend(_get_initial_animal_generators(species_name, current_animal_names)) + + for _ in range(NUM_GENERATIONS): + new_parent_names = _get_new_parents( + current_animal_names, previous_parent_sets, NUM_PARENTS) + previous_parent_sets.add(new_parent_names) + + parent_indices = sorted([ + index + for _, index in [ + extract_base_name_and_label(parent_name) + for parent_name in new_parent_names + ] + ]) + new_label = '(' + ''.join(parent_indices) + ')' + new_animal_name = create_name(species_name, new_label) + current_animal_names.append(new_animal_name) + command_list.append(_create_animal_statement(new_animal_name)) + for parent_name in sorted(new_parent_names): + new_edge = _create_animal_parent_of_statement(new_animal_name, parent_name) + command_list.append(new_edge) + + for animal_name in current_animal_names: + command_list.append(_create_animal_of_species_statement(animal_name, species_name)) + + return command_list diff --git a/scripts/generate_test_sql/species.py b/scripts/generate_test_sql/species.py new file mode 100644 index 000000000..9d3c68704 --- /dev/null +++ b/scripts/generate_test_sql/species.py @@ -0,0 +1,25 @@ +# Copyright 2017-present Kensho Technologies, LLC. +from .utils import create_vertex_statement, get_random_limbs, get_uuid + + +SPECIES_LIST = ( + 'Nazgul', + 'Pteranodon', + 'Dragon', + 'Hippogriff', +) + + +def _create_species_statement(species_name): + """Return a SQL statement to create a species vertex.""" + field_name_to_value = {'name': species_name, 'limbs': get_random_limbs(), 'uuid': get_uuid()} + return create_vertex_statement('Species', field_name_to_value) + + +def get_species_generation_commands(): + """Return a list of SQL statements to create all species vertices.""" + command_list = [] + for species_name in SPECIES_LIST: + command_list.append(_create_species_statement(species_name)) + + return command_list diff --git a/scripts/generate_test_sql/utils.py b/scripts/generate_test_sql/utils.py new file mode 100644 index 000000000..cf2257ce9 --- /dev/null +++ b/scripts/generate_test_sql/utils.py @@ -0,0 +1,87 @@ +# Copyright 2017-present Kensho Technologies, LLC. +import datetime +import random +from uuid import UUID + +import six + + +CREATE_VERTEX = 'create vertex ' +CREATE_EDGE = 'create edge ' +SEPARATOR = '__' + + +def get_uuid(): + """Return a pseudorandom uuid.""" + return str(UUID(int=random.randint(0, 2**128 - 1))) # nosec + + +def get_random_net_worth(): + """Return a pseudorandom net worth.""" + return int(1e5 * random.random()) / 100.0 # nosec + + +def get_random_limbs(): + """Return a pseudorandom number of limbs.""" + return random.randint(2, 10) # nosec + + +def get_random_date(): + """Return a pseudorandom date.""" + random_year = random.randint(2000, 2018) # nosec + random_month = random.randint(1, 12) # nosec + random_day = random.randint(1, 28) # nosec + return datetime.date(random_year, random_month, random_day) + + +def select_vertex_statement(vertex_type, name): + """Return a SQL statement to select a vertex of given type by its `name` field.""" + template = '(select from {vertex_type} where name = \'{name}\')' + args = {'vertex_type': vertex_type, 'name': name} + return template.format(**args) + + +def set_statement(field_name, field_value): + """Return a SQL clause (used in creating a vertex) to set a field to a value.""" + if not isinstance(field_name, six.string_types): + raise AssertionError(u'Expected string field_name. Received {}'.format(field_name)) + field_value_representation = repr(field_value) + if isinstance(field_value, datetime.date): + field_value_representation = 'DATE("' + field_value.isoformat() + ' 00:00:00")' + template = '{} = {}' + return template.format(field_name, field_value_representation) + + +def create_vertex_statement(vertex_type, field_name_to_value): + """Return a SQL statement to create a vertex.""" + statement = CREATE_VERTEX + vertex_type + set_field_clauses = [ + set_statement(field_name, field_name_to_value[field_name]) + for field_name in sorted(six.iterkeys(field_name_to_value)) + ] + statement += ' set ' + ', '.join(set_field_clauses) + return statement + + +def create_edge_statement(edge_name, from_class, from_name, to_class, to_name): + """Return a SQL statement to create a edge.""" + statement = CREATE_EDGE + edge_name + ' from {} to {}' + from_select = select_vertex_statement(from_class, from_name) + to_select = select_vertex_statement(to_class, to_name) + return statement.format(from_select, to_select) + + +def create_name(base_name, label): + """Return a name formed by joining a base name with a label.""" + return base_name + SEPARATOR + label + + +def extract_base_name_and_label(name): + """Extract and return a pair of (base_name, label) from a given name field.""" + if not isinstance(name, six.string_types): + raise AssertionError(u'Expected string name. Received {}'.format(name)) + split_name = name.split(SEPARATOR) + if len(split_name) != 2: + raise AssertionError(u'Expected a sting with a single occurrence of {}. Got {}' + .format(SEPARATOR, name)) + return split_name diff --git a/setup.py b/setup.py index 5a057c5bb..8093afe27 100644 --- a/setup.py +++ b/setup.py @@ -2,8 +2,10 @@ import codecs import os import re + from setuptools import find_packages, setup + # https://packaging.python.org/guides/single-sourcing-package-version/ # #single-sourcing-the-version