You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Summary
This PR integrates the fixes from PR #666 into the current
`arena-implementation` branch. PR #666 originally fixed IS_IN validation
and runtime handling for reserved properties, but the current
implementation has diverged significantly from when that PR was created.
## Problem
**Analyzer Issue**: The type validator incorrectly grouped `IS_IN` with
other boolean operations, expecting scalar arguments instead of arrays.
This caused compilation errors for queries like
`nodes::WHERE(_::{id}::IS_IN(node_ids))` when `node_ids` is `[ID]`.
**Runtime Issue**: The current implementation removed `filterable.rs`
and its special handling for reserved properties (id, label, etc.).
Reserved properties are now struct fields, not in the properties
HashMap, so `get_property("id")` returns `None`.
**Root Cause**:
1. IS_IN validation expects scalars instead of arrays
2. Reserved properties lost special handling during refactoring
3. Type mismatch between `Value::String` and `Value::Id` for ID
operations
## Solution
### 1. Added Reserved Property Support
- Created `ReservedProp` enum for built-in properties: Id, Label,
Version, FromNode, ToNode, Deleted, Level, Distance, Data
- Added `Step::ReservedPropertyAccess` variant to generate direct field
access
- Reserved properties now return correct Value types (e.g., `Value::Id`
for id field)
### 2. Updated Property Access Generator
- Modified `gen_property_access()` in `analyzer/utils.rs` to identify
reserved vs user-defined properties
- Reserved properties use direct struct field access:
`Value::Id(ID::from(val.id))`
- User-defined properties continue using `get_property()` HashMap lookup
### 3. Enhanced Boolean Operation Optimization
- Updated `WhereRef` Display implementation in `traversal_steps.rs` for
reserved properties
- Generates optimized filter code with correct Value types
- Example: `Value::Id(ID::from(val.id)).is_in(&data.node_ids)`
### 4. Fixed IS_IN Validation
- Separated IS_IN from scalar boolean operations in
`traversal_validation.rs`
- IS_IN now correctly expects `Type::Array(Box<Type::Scalar(ft)))`
arguments
- Added `get_reserved_property_type()` helper for type-safe validation
- Updated Node/Edge/Vector validation to check reserved properties first
## Files Changed
- `helix-db/src/helixc/generator/traversal_steps.rs` - Added
ReservedProp enum and Display logic
- `helix-db/src/helixc/analyzer/utils.rs` - Updated
gen_property_access()
- `helix-db/src/helixc/analyzer/methods/traversal_validation.rs` - Fixed
IS_IN validation and reserved property checking
- `hql-tests/tests/is_in/` - Added test cases for IS_IN with reserved
and user-defined properties
## Testing
Added comprehensive IS_IN tests:
```hql
QUERY GetNodes (fields: [String]) =>
node <- N<MyNode>::WHERE(_::{field}::IS_IN(fields))
RETURN node
QUERY GetNodesByID (node_ids: [ID]) =>
node <- N<MyNode>::WHERE(_::{id}::IS_IN(node_ids))
RETURN node
```
**Verified**:
- ✅ Queries compile successfully
- ✅ Correct code generation for reserved properties (direct field
access)
- ✅ Correct code generation for user-defined properties (get_property)
- ✅ Type safety maintained for array operations
## Generated Code Example
For reserved property `id`:
```rust
.filter_ref(|val, txn|{
if let Ok(val) = val {
Ok(Value::Id(ID::from(val.id)).is_in(&data.node_ids))
} else {
Ok(false)
}
})
```
For user-defined property `field`:
```rust
.filter_ref(|val, txn|{
if let Ok(val) = val {
Ok(val
.get_property("field")
.map_or(false, |v| v.is_in(&data.fields)))
} else {
Ok(false)
}
})
```
## Impact
- IS_IN operations now work correctly with arrays at compile-time and
runtime
- Reserved properties return proper Value types for IS_IN comparisons
- Queries like `WHERE(_::{id}::IS_IN(node_ids))` compile and execute
without panics
- No breaking changes to existing functionality
Co-Authored-By: ishaksebsib <[email protected]>
0 commit comments