Skip to content

fix(gfql): handle schema-changing operations in chains - #762

Merged
lmeyerov merged 5 commits into
masterfrom
fix/umap-chain-tracking-columns
Oct 10, 2025
Merged

lmeyerov merged 5 commits into
masterfrom
fix/umap-chain-tracking-columns

Conversation

@lmeyerov

@lmeyerov lmeyerov commented Oct 9, 2025 •

Copy link
Copy Markdown
Contributor

Fixes #761

Summary

Fix "Column 'index' not found in edges" error when UMAP or hypergraph operations are mixed with other GFQL operations in chains.

Implemented recursive dispatch that automatically splits chains at schema-changer boundaries, executing them as: before → schema_changer → rest. This ensures schema-changing operations (which create entirely new graph structures) are properly isolated from regular chain machinery.

Changes

Added

  • UMAP in chains: Can now use call('umap', {...}) mixed with filters and other operations
  • Hypergraph in chains: Removed mixing restriction - now allows [n(...), call('hypergraph', {...})]

Implementation

  • graphistry/compute/chain.py (lines 372-406): Recursive dispatch logic
    • Detects schema-changers (['umap', 'hypergraph']) in operation list
    • Handles singleton, multi-op, and nested cases
    • Falls through to existing chain logic when no schema-changers present
  • graphistry/tests/compute/test_gfql_schema_changers.py: New comprehensive test suite (8 scenarios)
  • graphistry/tests/compute/test_gfql_hypergraph.py: Updated to reflect new behavior

Test Coverage

Unit Tests

✅ Unit tests (compute): 396 passed, 49 skipped
✅ GFQL tests: 17/17 pass
✅ Chain tests: 25 passed, 3 skipped
✅ Lint (flake8): Pass
✅ Typecheck (mypy): Pass

Standalone Validation (10 scenarios in plans/fix-umap-chain-tracking/)

✅ Singleton operations: UMAP alone, hypergraph alone
✅ Multiple schema-changers: UMAP→UMAP, UMAP→hypergraph, n→umap→e→hypergraph→n
✅ Schema-changers at different positions: First, middle, last
✅ Mixed with filters: Filter→UMAP, UMAP→filter
✅ Edge cases: Empty before/after segments, consecutive schema-changers
✅ Let bindings: Schema-changers nested in let() constructs work correctly

All 10 standalone tests pass ✅

Example Usage

# Before: This would fail with "Column 'index' not found"
result = g.gfql([
    n({'type': 'person'}),
    call('umap', {'n_neighbors': 15}),
    e()
])

# Now: Works! Chain is split and executed as:
# g.chain([n(...)]) → g.chain([umap(...)]) → g.chain([e()])

Testing Notes

Schema-changers work correctly in:

  1. Direct chains: [n(), umap(), e()]
  2. Let bindings: let({'embedded': call('umap', ...)})
  3. Multiple schema-changers: [umap(), hypergraph()]
  4. Any position: Beginning, middle, or end of chain

lmeyerov and others added 2 commits October 9, 2025 16:05
Fix "Column 'index' not found in edges" error when UMAP or hypergraph
operations are mixed with other GFQL operations in chains.

Implemented recursive dispatch that automatically splits chains at
schema-changer boundaries, executing them as: before → schema_changer → rest.
This ensures schema-changing operations (which create entirely new graph
structures) are properly isolated from regular chain machinery.

Also removed the hypergraph mixing restriction, now allowing queries like:
[n(...), call('hypergraph', {...})]

Changes:
- graphistry/compute/chain.py: Added recursive dispatch logic (lines 372-406)
- graphistry/tests/compute/test_gfql_schema_changers.py: New comprehensive test suite
- graphistry/tests/compute/test_gfql_hypergraph.py: Updated to reflect new behavior
- CHANGELOG.md: Documented fix

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Import PyGraphistry and alias as CGFull to avoid F821 errors.
Fix W504 line break style in test assertions.
Comment thread graphistry/compute/chain.py
Comment thread graphistry/compute/chain.py Outdated
lmeyerov and others added 3 commits October 9, 2025 16:50
…ma-changers

- Add validate_schema check before execute_call() in singleton path
- Replace assert with proper GFQLTypeError exception for type checking
- Ensures user expectations for validation are honored
- Provides structured error messages instead of assertion failures

Related to #761

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…ndings

Create graphistry/tests/compute/gfql/ directory to mirror source structure
(following precedent from predicates/ tests). Add comprehensive tests for
schema-changing operations (UMAP, hypergraph) in let() bindings:

Coverage:
- Direct schema-changers in let bindings (execute_call path)
- Schema-changers in ASTRef chains (recursive dispatch path)
- Nested let() with schema-changers (recursive DAG execution)
- Mixed operations: filter → UMAP → hypergraph via refs

Tests are marked skip (require full Plotter) but document expected behavior
and execution paths for each scenario.

Related to #761

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Move test_gfql_schema_changers.py → gfql/test_schema_changers.py
  (follows new nested structure for GFQL tests)
- Update CHANGELOG.md with v0.43.1 release notes
  - Schema-changers in chains (feature + fix for #761)
  - validate_schema flag handling
  - GFQLTypeError exception handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@lmeyerov
lmeyerov merged commit 6be5ca8 into master Oct 10, 2025
69 checks passed
@lmeyerov
lmeyerov deleted the fix/umap-chain-tracking-columns branch October 10, 2025 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UMAP in GFQL chains fails with missing tracking column 'index'

1 participant