iris-vector-graph 1.63.0__tar.gz → 1.63.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/PKG-INFO +11 -3
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/README.md +8 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/Traversal.cls +42 -7
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/bulk_loader.py +5 -5
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher/translator.py +4 -1
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/engine.py +41 -6
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/schema.py +7 -32
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/pyproject.toml +3 -3
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_e2e_new_features.py +95 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/.gitignore +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/LICENSE +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/demo_biomedical.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/demo_fraud_detection.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/demo_fraud_detection_sql.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/demo_utils.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/demo_working_system.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical/loaders.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical/resolver.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical/types.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical_legacy/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical_legacy/biomedical_engine.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical_legacy/biomedical_schema.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical_legacy/legacy_wrapper.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/fraud/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/fraud/loaders.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/fraud/resolver.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/fraud/types.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/graphQL.http +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/hybrid_vector_graph_query.cypher +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/rest.http +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/Algorithms.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/ArnoAccel.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/BM25Index.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/BenchFormat.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/BenchSeeder.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/Benchmark.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/Edge.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/EdgeScan.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/GraphIndex.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/IVFIndex.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/Loader.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/MCPService.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/MCPToolSet.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/MCPTools.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/Meta.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/PLAIDSearch.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/PageRank.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/PyOps.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/Service.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/Snapshot.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/Subgraph.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/TemporalIndex.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/TestEdge.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/VecIndex.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/PageRankEmbedded.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/User.Exec.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/iris/vector/graph/GraphOperators.cls +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/bolt_server.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/capabilities.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher/algorithms/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher/algorithms/paths.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher/ast.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher/lexer.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher/parser.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher_api.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/embedded.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/fusion.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/gql/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/gql/constants.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/gql/engine.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/gql/pooling.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/gql/resolvers.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/gql/schema.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/models.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/operators.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/py.typed +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/security.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/text_search.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/utils.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/vector_utils.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/fhir_bridges.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/fraud_sample_data.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/globals_schema.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/graph_path_globals.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/graph_walk_tvf.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/migrations/000_base_schema_iris.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/migrations/001_add_nodepk_table.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/migrations/001_rollback_nodepk.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/migrations/002_add_fk_constraints.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/operators.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/operators_fixed.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/procedures/kg_PageRank.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/rdf_reifications.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/sql/schema.sql +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/TESTING.md +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/benchmark_parser.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/benchmarks/benchmark_neo4j.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/benchmarks/bfs_benchmark.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/benchmarks/establish_baseline.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/benchmarks/graph_gen.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/benchmarks/iris_baseline_run.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/benchmarks/iris_os_run.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/benchmarks/load_neo4j.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/benchmarks/synthetic_baseline.csv +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/conftest.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/contract/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/contract/test_cypher_api.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/contract/test_cypher_api_errors.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/contract/test_graphql_queries.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/contract/test_graphql_schema.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/contract/test_ppr_api.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/curl_suite.sh +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/conftest.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_biomedical_demo.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_biomedical_ui.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_cypher_coerce_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_cypher_sprints_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_cypher_vector_search.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_fhir_bridges_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_fraud_demo.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_fraud_ui.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_gql_autogen_startup.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_gql_cypher_passthrough.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_gql_node_queries.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_gql_semantic_search.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_gql_traversal.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_graph_kernels_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_hla_kg_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_multi_query_engine_platform.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_named_paths_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_nkg_index_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_operator_wiring_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_plaid_search_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_ppr_cls_fast_path.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_ppr_guided_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_procedure_installation.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_reification_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_schema_procedures_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_subgraph_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_subquery_call_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/e2e/test_vecindex_e2e.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/conftest.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/gql/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/gql/test_graphql_mutations.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/gql/test_graphql_nested_queries.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/gql/test_graphql_queries.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/gql/test_graphql_vector_search.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_bidirectional_ppr.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_cls_layer.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_cypher_advanced.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_cypher_enhancements.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_cypher_multi_type.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_cypher_rd.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_cypher_rel_vars.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_cypher_single_type.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_cypher_untyped.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_cypher_vector_search.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_embeddings_api.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_fastapi_graphql.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_fhir_bridges_integration.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_named_paths_integration.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_nodepk_advanced_benchmarks.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_nodepk_constraints.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_nodepk_graph_analytics.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_nodepk_migration.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_nodepk_performance.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_nodepk_production_scale.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_objectscript_classes.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_pagerank_sql_optimization.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_reification_integration.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_schema_migration.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_stored_procedure_install.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/integration/test_subquery_call_integration.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/performance/conftest.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/performance/scale_benchmark.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/performance/test_ppr_stress.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/performance/test_stress_v1_5.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/run_all_tests.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/test_iris_rest_api.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/test_networkx_loader.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/test_performance_benchmarks.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/test_pyops_vector_conversion.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/test_python_operators.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/test_python_sdk.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/test_schema_validation.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/test_sql_queries.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/python/test_vector_functions.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/cypher/__init__.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/cypher/test_lexer.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/cypher/test_lexer_advanced.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/cypher/test_parser.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/cypher/test_parser_advanced.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_batch_mutations.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_bfs_arno.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_bm25_index.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_bolt_server.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cls_deployment.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_benchmark.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_benchmark_scale.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_case_when.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_functions.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_parser.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_posos_bugs.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_procedures.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_translator.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_union_exists.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_var_length.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_vector_search.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_edge_embeddings.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_edgeprop_ndjson.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_embedded.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_engine_dimension_fix.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_engine_embeddings.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_fhir_bridges.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_get_nodes.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_graph_kernels.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_graphql_dataloader.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_ingest_formats.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_ivf_index.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_named_graphs.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_named_paths.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_operators_wiring.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_plaid_search.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_ppr_guided_subgraph.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_reification.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_schema_init.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_schema_procedures.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_shortest_path.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_snapshot.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_sql_splitter.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_sql_table_bridge.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_subgraph.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_subquery_call.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_temporal_cypher.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_temporal_edges.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_unified_edge_store.py +0 -0
- {iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_weighted_shortest_path.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iris-vector-graph
|
|
3
|
-
Version: 1.63.
|
|
3
|
+
Version: 1.63.2
|
|
4
4
|
Summary: Transactional Graph + Vector retrieval system for InterSystems IRIS with hybrid search, openCypher, and GraphQL APIs
|
|
5
5
|
Project-URL: Homepage, https://github.com/intersystems-community/iris-vector-graph
|
|
6
6
|
Project-URL: Documentation, https://github.com/intersystems-community/iris-vector-graph/tree/main/docs
|
|
@@ -23,14 +23,14 @@ Classifier: Topic :: Database
|
|
|
23
23
|
Classifier: Topic :: Scientific/Engineering
|
|
24
24
|
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
25
25
|
Requires-Python: >=3.10
|
|
26
|
-
Requires-Dist: intersystems-
|
|
26
|
+
Requires-Dist: intersystems-iris>=1.0.0
|
|
27
27
|
Provides-Extra: biodata
|
|
28
28
|
Requires-Dist: biopython>=1.81; extra == 'biodata'
|
|
29
29
|
Requires-Dist: bioservices>=1.11.0; extra == 'biodata'
|
|
30
30
|
Requires-Dist: mygene>=3.2.0; extra == 'biodata'
|
|
31
31
|
Requires-Dist: obonet>=1.0.0; extra == 'biodata'
|
|
32
32
|
Provides-Extra: core
|
|
33
|
-
Requires-Dist: intersystems-
|
|
33
|
+
Requires-Dist: intersystems-iris>=1.0.0; extra == 'core'
|
|
34
34
|
Provides-Extra: demo
|
|
35
35
|
Requires-Dist: python-fasthtml>=0.12.0; extra == 'demo'
|
|
36
36
|
Provides-Extra: dev
|
|
@@ -655,6 +655,14 @@ anchors = engine.get_kg_anchors(icd_codes=["J18.0", "E11.9"])
|
|
|
655
655
|
|
|
656
656
|
## Changelog
|
|
657
657
|
|
|
658
|
+
### v1.63.2 (2026-04-25)
|
|
659
|
+
- fix: `MATCH (a)-[r*1..N]-(b)` undirected BFS now traverses `^KG("in",...)` for inbound edges (was outbound-only)
|
|
660
|
+
- fix: `MATCH (a)<-[r*1..N]-(b)` inbound-only BFS now works
|
|
661
|
+
- fix: `initialize_schema()` ObjectScript LoadDir tries Docker `/tmp/src/` before Mac path — fixes silent compile failure in test containers
|
|
662
|
+
- 4 E2E tests: directed-out, undirected, multihop undirected, directed-in all passing
|
|
663
|
+
- Arno BFSJson falls back gracefully to BFSFastJson for graphs >3.5MB adjacency string (299K+ long-ID edges); per-seed export is spec 079 future work
|
|
664
|
+
|
|
665
|
+
|
|
658
666
|
### v1.63.0 (2026-04-25)
|
|
659
667
|
- feat: Arno/Rust fast path for BFS (`_execute_var_length_cypher`) — when `libarno_callout.so` is loaded with `Graph.KG.NKGAccel.BFSJson`, var-length Cypher queries use Rust BFS over `^NKG` integer adjacency instead of ObjectScript `BFSFastJson`. Projected 128ms → <30ms p50 for 6K+ result BFS at 10K/50K scale. Falls back transparently to `BFSFastJson` when Arno not loaded. (spec 079, arno spec 035)
|
|
660
668
|
|
|
@@ -583,6 +583,14 @@ anchors = engine.get_kg_anchors(icd_codes=["J18.0", "E11.9"])
|
|
|
583
583
|
|
|
584
584
|
## Changelog
|
|
585
585
|
|
|
586
|
+
### v1.63.2 (2026-04-25)
|
|
587
|
+
- fix: `MATCH (a)-[r*1..N]-(b)` undirected BFS now traverses `^KG("in",...)` for inbound edges (was outbound-only)
|
|
588
|
+
- fix: `MATCH (a)<-[r*1..N]-(b)` inbound-only BFS now works
|
|
589
|
+
- fix: `initialize_schema()` ObjectScript LoadDir tries Docker `/tmp/src/` before Mac path — fixes silent compile failure in test containers
|
|
590
|
+
- 4 E2E tests: directed-out, undirected, multihop undirected, directed-in all passing
|
|
591
|
+
- Arno BFSJson falls back gracefully to BFSFastJson for graphs >3.5MB adjacency string (299K+ long-ID edges); per-seed export is spec 079 future work
|
|
592
|
+
|
|
593
|
+
|
|
586
594
|
### v1.63.0 (2026-04-25)
|
|
587
595
|
- feat: Arno/Rust fast path for BFS (`_execute_var_length_cypher`) — when `libarno_callout.so` is loaded with `Graph.KG.NKGAccel.BFSJson`, var-length Cypher queries use Rust BFS over `^NKG` integer adjacency instead of ObjectScript `BFSFastJson`. Projected 128ms → <30ms p50 for 6K+ result BFS at 10K/50K scale. Falls back transparently to `BFSFastJson` when Arno not loaded. (spec 079, arno spec 035)
|
|
588
596
|
|
|
@@ -151,8 +151,9 @@ ClassMethod TraverseAllPredicates(s As %String, hop As %Integer, maxHops As %Int
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/// Optimized BFS using Process-Private Globals and $ListBuild to bypass object bottleneck
|
|
154
|
+
/// @param direction "out" (default), "in", or "both" for undirected BFS
|
|
154
155
|
/// @returns Number of edges found. Results are in ^||BFS.Results(i) = $lb(s, p, o, w, step)
|
|
155
|
-
ClassMethod BFSFast(srcId As %String, preds As %DynamicArray = "", maxHops As %Integer = 2, dstLabel As %String = "") As %Integer
|
|
156
|
+
ClassMethod BFSFast(srcId As %String, preds As %DynamicArray = "", maxHops As %Integer = 2, dstLabel As %String = "", direction As %String = "out") As %Integer
|
|
156
157
|
{
|
|
157
158
|
Kill ^||BFS.Results
|
|
158
159
|
If (srcId = "") || (maxHops <= 0) Return 0
|
|
@@ -171,10 +172,20 @@ ClassMethod BFSFast(srcId As %String, preds As %DynamicArray = "", maxHops As %I
|
|
|
171
172
|
Set s = $Order(frontier(s))
|
|
172
173
|
If s = "" Quit
|
|
173
174
|
|
|
174
|
-
If
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
If direction = "out" || (direction = "both") {
|
|
176
|
+
If fixedP '= "" {
|
|
177
|
+
Do ..TraverseWithPredicateFast(s, fixedP, hop, maxHops, nextP, dstLabel, .count, .nextFrontier, .seen)
|
|
178
|
+
} Else {
|
|
179
|
+
Do ..TraverseAllPredicatesFast(s, hop, maxHops, nextP, dstLabel, .count, .nextFrontier, .seen)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
If direction = "in" || (direction = "both") {
|
|
184
|
+
If fixedP '= "" {
|
|
185
|
+
Do ..TraverseWithPredicateFastInbound(s, fixedP, hop, .count, .nextFrontier, .seen)
|
|
186
|
+
} Else {
|
|
187
|
+
Do ..TraverseAllPredicatesFastInbound(s, hop, .count, .nextFrontier, .seen)
|
|
188
|
+
}
|
|
178
189
|
}
|
|
179
190
|
}
|
|
180
191
|
|
|
@@ -216,6 +227,30 @@ ClassMethod TraverseAllPredicatesFast(s As %String, hop As %Integer, maxHops As
|
|
|
216
227
|
}
|
|
217
228
|
}
|
|
218
229
|
|
|
230
|
+
/// Inbound BFS: traverse ^KG("in", 0, s, p, o) where s is the target, o is the source.
|
|
231
|
+
/// Result stored as (o, p, s) to preserve original edge direction.
|
|
232
|
+
ClassMethod TraverseWithPredicateFastInbound(s As %String, p As %String, hop As %Integer, ByRef count As %Integer, ByRef nextFrontier, ByRef seen) [ Internal, Private ]
|
|
233
|
+
{
|
|
234
|
+
Set o = ""
|
|
235
|
+
For {
|
|
236
|
+
Set o = $Order(^KG("in", 0, s, p, o))
|
|
237
|
+
If o = "" Quit
|
|
238
|
+
Set count = count + 1
|
|
239
|
+
Set ^||BFS.Results(count) = $ListBuild(s, p, o, $Get(^KG("out", 0, o, p, s), 1.0), hop)
|
|
240
|
+
If '$Data(seen(o)) Set nextFrontier(o) = ""
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
ClassMethod TraverseAllPredicatesFastInbound(s As %String, hop As %Integer, ByRef count As %Integer, ByRef nextFrontier, ByRef seen) [ Internal, Private ]
|
|
245
|
+
{
|
|
246
|
+
Set p = ""
|
|
247
|
+
For {
|
|
248
|
+
Set p = $Order(^KG("in", 0, s, p))
|
|
249
|
+
If p = "" Quit
|
|
250
|
+
Do ..TraverseWithPredicateFastInbound(s, p, hop, .count, .nextFrontier, .seen)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
219
254
|
/// Main BFS implementation
|
|
220
255
|
ClassMethod BFS(srcId As %String, preds As %DynamicArray = "", maxHops As %Integer = 2, dstLabel As %String = "") As %DynamicArray
|
|
221
256
|
{
|
|
@@ -287,7 +322,7 @@ ClassMethod BFSJSON(srcId As %String, preds As %DynamicArray, maxHops As %Intege
|
|
|
287
322
|
/// @param maxHops Maximum hops (default 2)
|
|
288
323
|
/// @param dstLabel Filter destination nodes by label (empty = no filter)
|
|
289
324
|
/// @returns JSON array: [{"s":..,"p":..,"o":..,"w":..,"step":..}, ...] in traversal order
|
|
290
|
-
ClassMethod BFSFastJson(srcId As %String, predsJson As %String = "", maxHops As %Integer = 2, dstLabel As %String = "") As %String
|
|
325
|
+
ClassMethod BFSFastJson(srcId As %String, predsJson As %String = "", maxHops As %Integer = 2, dstLabel As %String = "", direction As %String = "out") As %String
|
|
291
326
|
{
|
|
292
327
|
// Parse predicates JSON into a %DynamicArray (null/"" means all predicates)
|
|
293
328
|
Set preds = ""
|
|
@@ -300,7 +335,7 @@ ClassMethod BFSFastJson(srcId As %String, predsJson As %String = "", maxHops As
|
|
|
300
335
|
}
|
|
301
336
|
|
|
302
337
|
// Run BFSFast -- writes to ^||BFS.Results(i) = $ListBuild(s,p,o,w,step)
|
|
303
|
-
Set count = ..BFSFast(srcId, preds, maxHops, dstLabel)
|
|
338
|
+
Set count = ..BFSFast(srcId, preds, maxHops, dstLabel, direction)
|
|
304
339
|
|
|
305
340
|
If count = 0 Return "[]"
|
|
306
341
|
|
|
@@ -273,8 +273,8 @@ class BulkLoader:
|
|
|
273
273
|
Must be called after load_edges(use_noindex=True).
|
|
274
274
|
Also rebuilds bitmap extent indexes for correct COUNT(*).
|
|
275
275
|
"""
|
|
276
|
-
import
|
|
277
|
-
iris_obj =
|
|
276
|
+
import iris
|
|
277
|
+
iris_obj = iris.createIRIS(self.conn)
|
|
278
278
|
results = {}
|
|
279
279
|
|
|
280
280
|
for cls in ["Graph.KG.rdfedges", "Graph.KG.rdflabels", "Graph.KG.rdfprops", "Graph.KG.nodes"]:
|
|
@@ -301,8 +301,8 @@ class BulkLoader:
|
|
|
301
301
|
Returns True if successful.
|
|
302
302
|
"""
|
|
303
303
|
try:
|
|
304
|
-
import
|
|
305
|
-
iris_obj =
|
|
304
|
+
import iris
|
|
305
|
+
iris_obj = iris.createIRIS(self.conn)
|
|
306
306
|
logger.info("Building ^KG + ^NKG globals from SQL tables...")
|
|
307
307
|
t0 = time.time()
|
|
308
308
|
iris_obj.classMethodVoid("Graph.KG.Traversal", "BuildKG")
|
|
@@ -422,7 +422,7 @@ def main():
|
|
|
422
422
|
logger.info(f"Graph: {G.number_of_nodes():,} nodes, {G.number_of_edges():,} edges")
|
|
423
423
|
|
|
424
424
|
|
|
425
|
-
from
|
|
425
|
+
from iris.dbapi._DBAPI import connect # intersystems_iris.dbapi = iris.dbapi
|
|
426
426
|
conn = connect(args.host, args.port, args.namespace, args.user, args.password)
|
|
427
427
|
logger.info(f"Connected to IRIS {args.host}:{args.port}/{args.namespace}")
|
|
428
428
|
|
{iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher/translator.py
RENAMED
|
@@ -1744,6 +1744,9 @@ def translate_relationship_pattern(
|
|
|
1744
1744
|
def _resolve_id_param(node):
|
|
1745
1745
|
id_val = node.properties.get("id")
|
|
1746
1746
|
if id_val is None:
|
|
1747
|
+
if node.variable and node.variable in context.input_params:
|
|
1748
|
+
val = context.input_params[node.variable]
|
|
1749
|
+
return f"${node.variable}" if isinstance(val, str) else None
|
|
1747
1750
|
return None
|
|
1748
1751
|
if isinstance(id_val, ast.Variable):
|
|
1749
1752
|
return f"${id_val.name}"
|
|
@@ -1756,7 +1759,7 @@ def translate_relationship_pattern(
|
|
|
1756
1759
|
src_id_param = _resolve_id_param(source_node)
|
|
1757
1760
|
dst_id_param = _resolve_id_param(target_node)
|
|
1758
1761
|
|
|
1759
|
-
direction_str = "both" if rel.direction == ast.Direction.BOTH else "out"
|
|
1762
|
+
direction_str = "both" if rel.direction == ast.Direction.BOTH else ("in" if rel.direction == ast.Direction.INCOMING else "out")
|
|
1760
1763
|
|
|
1761
1764
|
context.var_length_paths.append(
|
|
1762
1765
|
{
|
|
@@ -1025,6 +1025,31 @@ class IRISGraphEngine:
|
|
|
1025
1025
|
source_id = _resolve(vl.get("src_id_param"))
|
|
1026
1026
|
target_id = _resolve(vl.get("dst_id_param"))
|
|
1027
1027
|
|
|
1028
|
+
if source_id is None and parameters:
|
|
1029
|
+
src_var = vl.get("source_var")
|
|
1030
|
+
if src_var and src_var in parameters:
|
|
1031
|
+
source_id = str(parameters[src_var])
|
|
1032
|
+
else:
|
|
1033
|
+
source_id = next(
|
|
1034
|
+
(str(v) for v in parameters.values() if isinstance(v, str)), None
|
|
1035
|
+
)
|
|
1036
|
+
|
|
1037
|
+
if target_id is None and parameters:
|
|
1038
|
+
dst_var = vl.get("target_var")
|
|
1039
|
+
if dst_var and dst_var in parameters:
|
|
1040
|
+
target_id = str(parameters[dst_var])
|
|
1041
|
+
else:
|
|
1042
|
+
vals = [str(v) for v in parameters.values() if isinstance(v, str)]
|
|
1043
|
+
target_id = vals[1] if len(vals) > 1 else None
|
|
1044
|
+
|
|
1045
|
+
if source_id is None or target_id is None:
|
|
1046
|
+
sql_params = sql_query.parameters[0] if sql_query.parameters else []
|
|
1047
|
+
str_params = [p for p in sql_params if isinstance(p, str) and not p.startswith("Graph_KG")]
|
|
1048
|
+
if source_id is None and len(str_params) >= 1:
|
|
1049
|
+
source_id = str_params[0]
|
|
1050
|
+
if target_id is None and len(str_params) >= 2:
|
|
1051
|
+
target_id = str_params[1]
|
|
1052
|
+
|
|
1028
1053
|
if source_id is None or target_id is None:
|
|
1029
1054
|
raise ValueError(
|
|
1030
1055
|
"shortestPath requires both source and target node IDs to be bound. "
|
|
@@ -1131,7 +1156,11 @@ class IRISGraphEngine:
|
|
|
1131
1156
|
source_id = item
|
|
1132
1157
|
break
|
|
1133
1158
|
if source_id is None and parameters:
|
|
1134
|
-
|
|
1159
|
+
src_var = vl.get("source_var")
|
|
1160
|
+
if src_var and src_var in parameters:
|
|
1161
|
+
source_id = str(parameters[src_var])
|
|
1162
|
+
else:
|
|
1163
|
+
source_id = next(iter(parameters.values()), None)
|
|
1135
1164
|
|
|
1136
1165
|
if source_id is None:
|
|
1137
1166
|
return {
|
|
@@ -1177,6 +1206,7 @@ class IRISGraphEngine:
|
|
|
1177
1206
|
predicates_json,
|
|
1178
1207
|
max_hops,
|
|
1179
1208
|
"",
|
|
1209
|
+
vl.get("direction", "out"),
|
|
1180
1210
|
)
|
|
1181
1211
|
bfs_results = _json.loads(str(bfs_json)) if bfs_json else []
|
|
1182
1212
|
except Exception as e:
|
|
@@ -1214,9 +1244,14 @@ class IRISGraphEngine:
|
|
|
1214
1244
|
seen.add(oid)
|
|
1215
1245
|
target_ids.append(oid)
|
|
1216
1246
|
|
|
1247
|
+
import re as _re
|
|
1248
|
+
sql_str = sql_query.sql if isinstance(sql_query.sql, str) else ""
|
|
1249
|
+
alias_match = _re.search(r'SELECT\s+DISTINCT\s+\S+\s+AS\s+(\w+)|SELECT\s+\S+\s+AS\s+(\w+)', sql_str, _re.IGNORECASE)
|
|
1250
|
+
col_name = (alias_match.group(1) or alias_match.group(2)) if alias_match else "b_id"
|
|
1251
|
+
|
|
1217
1252
|
if not target_ids:
|
|
1218
1253
|
return {
|
|
1219
|
-
"columns": [
|
|
1254
|
+
"columns": [col_name, "b_labels", "b_props"],
|
|
1220
1255
|
"rows": [],
|
|
1221
1256
|
"sql": "",
|
|
1222
1257
|
"params": [],
|
|
@@ -1236,7 +1271,7 @@ class IRISGraphEngine:
|
|
|
1236
1271
|
)
|
|
1237
1272
|
|
|
1238
1273
|
return {
|
|
1239
|
-
"columns": [
|
|
1274
|
+
"columns": [col_name, "b_labels", "b_props"],
|
|
1240
1275
|
"rows": [list(r) for r in rows],
|
|
1241
1276
|
"sql": f"BFSFastJson({source_id}, {predicates_json}, {max_hops})",
|
|
1242
1277
|
"params": [],
|
|
@@ -4853,7 +4888,7 @@ class IRISGraphEngine:
|
|
|
4853
4888
|
try:
|
|
4854
4889
|
iris_obj = self._iris_obj()
|
|
4855
4890
|
result = iris_obj.classMethodValue(
|
|
4856
|
-
"Graph.KG.Traversal", "BFSFastJson", seed, "", hops, ""
|
|
4891
|
+
"Graph.KG.Traversal", "BFSFastJson", seed, "", hops, "", "out"
|
|
4857
4892
|
)
|
|
4858
4893
|
if result:
|
|
4859
4894
|
edges = json.loads(str(result))
|
|
@@ -4916,9 +4951,9 @@ class IRISGraphEngine:
|
|
|
4916
4951
|
|
|
4917
4952
|
return iris.createIRIS(self.conn)
|
|
4918
4953
|
except (TypeError, AttributeError):
|
|
4919
|
-
import
|
|
4954
|
+
import iris
|
|
4920
4955
|
|
|
4921
|
-
return
|
|
4956
|
+
return iris.createIRIS(self.conn)
|
|
4922
4957
|
|
|
4923
4958
|
def vec_create_index(
|
|
4924
4959
|
self,
|
|
@@ -17,43 +17,18 @@ logger = logging.getLogger(__name__)
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def _call_classmethod(conn_or_cursor, class_name: str, method_name: str, *args) -> Any:
|
|
20
|
-
"""Call an IRIS ObjectScript class method using the native API.
|
|
21
|
-
|
|
22
|
-
Works with both the ``iris`` package (iris.createIRIS) and the
|
|
23
|
-
``intersystems_iris`` package (intersystems_iris.createIRIS). Tries
|
|
24
|
-
``iris.createIRIS`` first because it accepts the connection objects
|
|
25
|
-
returned by ``iris.connect()`` (the standard test-fixture connection).
|
|
26
|
-
|
|
27
|
-
Resolves the connection from either a connection object directly or from
|
|
28
|
-
``cursor._connection`` if a cursor is passed.
|
|
29
|
-
|
|
30
|
-
Returns the method's return value, or raises if the class/method does not
|
|
31
|
-
exist or the native API is unavailable.
|
|
32
|
-
"""
|
|
33
|
-
# Accept either a connection or a cursor
|
|
34
20
|
if hasattr(conn_or_cursor, "cursor"):
|
|
35
|
-
conn = conn_or_cursor
|
|
21
|
+
conn = conn_or_cursor
|
|
36
22
|
elif hasattr(conn_or_cursor, "_connection"):
|
|
37
|
-
conn = conn_or_cursor._connection
|
|
23
|
+
conn = conn_or_cursor._connection
|
|
38
24
|
else:
|
|
39
|
-
conn = conn_or_cursor
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
try:
|
|
43
|
-
import iris as _iris_pkg # type: ignore[import]
|
|
44
|
-
|
|
45
|
-
iris_obj = _iris_pkg.createIRIS(conn)
|
|
46
|
-
return iris_obj.classMethodValue(class_name, method_name, *args)
|
|
47
|
-
except (ImportError, AttributeError, TypeError):
|
|
48
|
-
pass
|
|
49
|
-
|
|
50
|
-
# Fall back to intersystems_iris.createIRIS (accepts intersystems_iris.IRISConnection)
|
|
51
|
-
import intersystems_iris as _iris_pkg2 # type: ignore[import]
|
|
52
|
-
|
|
53
|
-
iris_obj = _iris_pkg2.createIRIS(conn)
|
|
25
|
+
conn = conn_or_cursor
|
|
26
|
+
import iris as _iris_pkg
|
|
27
|
+
iris_obj = _iris_pkg.createIRIS(conn)
|
|
54
28
|
return iris_obj.classMethodValue(class_name, method_name, *args)
|
|
55
29
|
|
|
56
30
|
|
|
31
|
+
|
|
57
32
|
class GraphSchema:
|
|
58
33
|
"""Domain-agnostic RDF-style graph schema management"""
|
|
59
34
|
|
|
@@ -782,7 +757,7 @@ LANGUAGE OBJECTSCRIPT
|
|
|
782
757
|
|
|
783
758
|
src_dir = str(iris_src_path / "src") if iris_src_path else ""
|
|
784
759
|
deployed = False
|
|
785
|
-
for candidate_dir in [
|
|
760
|
+
for candidate_dir in ["/tmp/src/", "/irisdev/app/iris_src/src/", src_dir]:
|
|
786
761
|
if not candidate_dir:
|
|
787
762
|
continue
|
|
788
763
|
try:
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "iris-vector-graph"
|
|
7
|
-
version = "1.63.
|
|
7
|
+
version = "1.63.2"
|
|
8
8
|
description = "Transactional Graph + Vector retrieval system for InterSystems IRIS with hybrid search, openCypher, and GraphQL APIs"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -38,12 +38,12 @@ requires-python = ">=3.10"
|
|
|
38
38
|
|
|
39
39
|
# Core dependencies
|
|
40
40
|
dependencies = [
|
|
41
|
-
"intersystems-
|
|
41
|
+
"intersystems-iris>=1.0.0",
|
|
42
42
|
]
|
|
43
43
|
|
|
44
44
|
[project.optional-dependencies]
|
|
45
45
|
core = [
|
|
46
|
-
"intersystems-
|
|
46
|
+
"intersystems-iris>=1.0.0",
|
|
47
47
|
]
|
|
48
48
|
full = [
|
|
49
49
|
"numpy>=1.24.0",
|
{iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/tests/unit/test_cypher_e2e_new_features.py
RENAMED
|
@@ -457,3 +457,98 @@ class TestCypherRound2E2E:
|
|
|
457
457
|
q = "MATCH (n) WHERE n.id = $id CALL ivg.vector.search('Gene','embedding',[0.1,0.2,0.3,0.4],5) YIELD node, score RETURN n.id, node, score"
|
|
458
458
|
r = translate_to_sql(parse_query(q), {"id": "x"})
|
|
459
459
|
assert r.var_length_paths is not None or r.sql is not None
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
@pytest.mark.skipif(SKIP_IRIS_TESTS, reason="SKIP_IRIS_TESTS=true")
|
|
463
|
+
class TestUndirectedBFSE2E:
|
|
464
|
+
|
|
465
|
+
@pytest.fixture(autouse=True)
|
|
466
|
+
def setup(self, iris_connection):
|
|
467
|
+
from iris_vector_graph.engine import IRISGraphEngine
|
|
468
|
+
self.conn = iris_connection
|
|
469
|
+
self.engine = IRISGraphEngine(iris_connection, embedding_dimension=4)
|
|
470
|
+
self.engine.initialize_schema()
|
|
471
|
+
self._run = uuid.uuid4().hex[:8]
|
|
472
|
+
self._nodes = []
|
|
473
|
+
yield
|
|
474
|
+
cursor = self.conn.cursor()
|
|
475
|
+
for nid in self._nodes:
|
|
476
|
+
try:
|
|
477
|
+
cursor.execute("DELETE FROM Graph_KG.rdf_edges WHERE s=? OR o_id=?", [nid, nid])
|
|
478
|
+
cursor.execute("DELETE FROM Graph_KG.rdf_labels WHERE s=?", [nid])
|
|
479
|
+
cursor.execute("DELETE FROM Graph_KG.nodes WHERE node_id=?", [nid])
|
|
480
|
+
except Exception:
|
|
481
|
+
pass
|
|
482
|
+
try:
|
|
483
|
+
self.conn.commit()
|
|
484
|
+
except Exception:
|
|
485
|
+
self.conn.rollback()
|
|
486
|
+
|
|
487
|
+
def _node(self, suffix):
|
|
488
|
+
nid = f"ubfs_{self._run}_{suffix}"
|
|
489
|
+
self._nodes.append(nid)
|
|
490
|
+
self.engine.create_node(nid, labels=["Gene"])
|
|
491
|
+
return nid
|
|
492
|
+
|
|
493
|
+
def _edge(self, s, p, o):
|
|
494
|
+
self.engine.create_edge(s, p, o)
|
|
495
|
+
|
|
496
|
+
def test_directed_out_returns_outbound_only(self):
|
|
497
|
+
a = self._node("A")
|
|
498
|
+
b = self._node("B")
|
|
499
|
+
c = self._node("C")
|
|
500
|
+
self._edge(a, "REL", b)
|
|
501
|
+
self._edge(c, "REL", a)
|
|
502
|
+
|
|
503
|
+
result = self.engine.execute_cypher(
|
|
504
|
+
"MATCH (x)-[r*1..1]->(y) WHERE x.id = $id RETURN y.id",
|
|
505
|
+
{"id": a},
|
|
506
|
+
)
|
|
507
|
+
ids = {row[0] for row in result["rows"]}
|
|
508
|
+
assert b in ids
|
|
509
|
+
assert c not in ids
|
|
510
|
+
|
|
511
|
+
def test_undirected_returns_both_inbound_and_outbound(self):
|
|
512
|
+
a = self._node("hub")
|
|
513
|
+
b = self._node("outbound")
|
|
514
|
+
c = self._node("inbound")
|
|
515
|
+
self._edge(a, "REL", b)
|
|
516
|
+
self._edge(c, "REL", a)
|
|
517
|
+
|
|
518
|
+
result = self.engine.execute_cypher(
|
|
519
|
+
"MATCH (x)-[r*1..1]-(y) WHERE x.id = $id RETURN y.id",
|
|
520
|
+
{"id": a},
|
|
521
|
+
)
|
|
522
|
+
ids = {row[0] for row in result["rows"]}
|
|
523
|
+
assert b in ids, f"outbound neighbor missing: {ids}"
|
|
524
|
+
assert c in ids, f"inbound neighbor missing: {ids}"
|
|
525
|
+
|
|
526
|
+
def test_undirected_multihop(self):
|
|
527
|
+
a = self._node("mh_a")
|
|
528
|
+
b = self._node("mh_b")
|
|
529
|
+
c = self._node("mh_c")
|
|
530
|
+
self._edge(b, "REL", a)
|
|
531
|
+
self._edge(b, "REL", c)
|
|
532
|
+
|
|
533
|
+
result = self.engine.execute_cypher(
|
|
534
|
+
"MATCH (x)-[r*1..2]-(y) WHERE x.id = $id RETURN y.id",
|
|
535
|
+
{"id": a},
|
|
536
|
+
)
|
|
537
|
+
ids = {row[0] for row in result["rows"]}
|
|
538
|
+
assert b in ids
|
|
539
|
+
assert c in ids
|
|
540
|
+
|
|
541
|
+
def test_directed_in_returns_inbound_only(self):
|
|
542
|
+
a = self._node("tgt")
|
|
543
|
+
b = self._node("src")
|
|
544
|
+
c = self._node("other")
|
|
545
|
+
self._edge(b, "REL", a)
|
|
546
|
+
self._edge(a, "REL", c)
|
|
547
|
+
|
|
548
|
+
result = self.engine.execute_cypher(
|
|
549
|
+
"MATCH (x)<-[r*1..1]-(y) WHERE x.id = $id RETURN y.id",
|
|
550
|
+
{"id": a},
|
|
551
|
+
)
|
|
552
|
+
ids = {row[0] for row in result["rows"]}
|
|
553
|
+
assert b in ids, f"inbound src missing: {ids}"
|
|
554
|
+
assert c not in ids, f"outbound dst should not appear: {ids}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical/__init__.py
RENAMED
|
File without changes
|
{iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical/loaders.py
RENAMED
|
File without changes
|
{iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical/resolver.py
RENAMED
|
File without changes
|
|
File without changes
|
{iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/domains/biomedical_legacy/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/examples/hybrid_vector_graph_query.cypher
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_src/src/Graph/KG/TemporalIndex.cls
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iris_vector_graph-1.63.0 → iris_vector_graph-1.63.2}/iris_vector_graph/cypher/algorithms/paths.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|