Restore resolveLanguage alongside resolveLiteral#865
Merged
lucksus merged 9 commits intoJun 19, 2026
Merged
Conversation
…data model Restores resolve_language (general expression-language selector) as a first-class field on ShapeProperty and PropertyShape, kept beside the resolve_literal optimization flag added on this branch. - types.rs / shacl_parser.rs: resolve_language: Option<String> re-added. - parse_shacl_to_links: emits both ad4m://resolveLanguage and ad4m://resolveLiteral links when set. - shape.rs (load_shape + load_shape_from_meta): populates resolve_language from RDF/meta; resolve_literal still derived from resolveLanguage for backward compat when the explicit flag is absent. resolve_language is the dev mechanism (route values through any language); resolve_literal is the literal-only deterministic-storage optimization. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restore get_resolve_language_from_shacl (string selector) beside
get_resolve_literal_from_shacl. resolve_property_value now applies the
unified precedence:
1. custom resolve_language (!= "literal") -> expression_create(lang)
-> signed-envelope URI (the dev behavior, lenient fallback on error)
2. literal language + resolveLiteral: false -> expression_create("literal")
3. otherwise -> deterministic literal: IRI (optimized default)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lve_literal Add ShapeProperty::is_deterministic_literal() — true only for the literal language (explicit or default) with resolve_literal != Some(false). Custom languages always produce signed envelopes, so they are never deterministic. - sparql_builder / projection: WHERE matching uses is_deterministic_literal() to decide typed-literal VALUES vs FILTER-on-decoded probing. - query.rs resolve_language_transforms: now fetches+transforms any non-deterministic-literal property (custom language OR resolveLiteral:false), restoring dev's general expression-resolution read path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ShaclProperty carries resolve_language beside resolve_literal again, read from ad4m://resolveLanguage in load_class_properties_with_uri. Add resolve_property_resolve_language helper beside resolve_property_resolve_literal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… layer resolveLanguage (general expression-language selector, default "literal") is a first-class @Property option again, kept alongside the resolveLiteral literal-storage optimization added on this branch. - decorators / types: resolveLanguage?: string re-added; Property() defaults it to "literal", resolveLiteral to true. - sdna: emits property_resolve_language with the actual language again. - shacl-gen / SHACLShape / json-schema: carry + round-trip both fields (ad4m://resolveLanguage and ad4m://resolveLiteral links). - Ad4mModel write path + query builders (query-sparql, query-utils, PerspectiveProxy): unified precedence — custom language -> createExpression on that language; literal + resolveLiteral:false -> createExpression on literal; else deterministic literal: IRI. Custom languages are never treated as deterministic-literal storage in WHERE building. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…empty-string - Rust: struct-literal test fixtures carry both fields; shape.rs preserves an explicit empty resolve_language verbatim (matching dev) rather than coercing to None. New round_trip tests for resolve_literal true/false and a custom resolve_language, asserting is_deterministic_literal() classification. - integration test exercises the non-literal FILTER path via a custom resolveLanguage on the target shape. - TS: SHACLShape round-trip tests for resolveLanguage (toJSON/fromJSON and toLinks/fromLinks) and the resolveLanguage+resolveLiteral pairing. Full Rust suite (640) and core TS suite (260) green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… deterministic literals
Two read/write-path gaps surfaced by the resolveLanguage+resolveLiteral
integration tests:
1. resolve_property_value (write, createSubject / MCP path) only encoded
String and Number for deterministic-literal properties; Bool, Object and
Array fell through to `value.to_string()` and were stored as opaque raw
targets (`false`, `{...}`) instead of `literal:boolean:` / `literal:json:`
IRIs. The typed-literal storage layer then kept them as NamedNodes, so
reads returned strings and indexed WHERE filters never matched. Encode
Bool as `literal:boolean:{b}` and Object/Array via Literal::from_json,
matching the TS `valueToLiteralIri` encoding.
2. resolve_language_transforms skipped deterministic-literal properties, so a
property with `resolveLanguage: "literal"` plus a transform never had its
transform applied on read. Include properties that carry a transform, and
use the already-decoded hydrated value as the transform focus (never
re-interpreting it as an expression URL).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…th-resolve-literal' into feat/restore-resolve-language-with-resolve-literal
691d92c
into
refactor/typed-rdf-literals-and-fn-cleanup
8 checks passed
10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
based on #842
Why
That branch's
resolveLanguage→resolveLiteralrefactor (073cfd4) collapsed two distinct concepts into one boolean and removed resolveLanguage as a public API. That's a breaking change for dev: existing@Property({ resolveLanguage: "..." })user code silently stops working, and the general ability to resolve a property's value through an arbitrary language (not just literal) was lost — values could only be stored as deterministic literals or as signed envelopes on the literal language.This PR brings
resolveLanguageback as the first-class, general mechanism it is in dev, while keepingresolveLiteralas the literal-only storage optimization it was introduced to be. Both coexist.Model
Write precedence: custom language → expression_create(lang); literal + resolveLiteral: false → expression_create("literal"); otherwise → deterministic literal: IRI.
A custom resolveLanguage is never treated as deterministic-literal storage, so WHERE matching correctly uses FILTER(STR(?v)=…) on decoded values rather than a typed-literal VALUES clause.
Changes (one commit per layer)
absent).
unified precedence as Rust.
Backward compatibility
Tests
Review notes — two design calls
🤖 Generated with Claude Code