Pometry / Pometry/Raphtory

Restructure ReadExpr: encode expression/wrapper validity in types

Open
#2,727 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
642
Forks
70
Avg merge
2d 13h
Merged PRs (30d)
21

Description

The remote client's ReadExpr is a flat enum; the relationships between what is a valid input to one expression and its wrapping expression are lost, and validity is enforced ad hoc at render/parse time. Restructure so invalid trees are unrepresentable (typed stages or a builder), which also removes a class of runtime InvalidResponse/InvalidInput checks.

In scope: each terminal's shape is declared three times

A related symptom of the same flat structure: every terminal's wire shape lives in three independent places that must agree, and a mismatch compiles fine and only fails at runtime.

Worked example — changing earliestEdgeTime from a bare i64 to an EventTime required editing all three:

// 1. render — which sub-fields to select
out.push_str(" { earliestEdgeTime { timestamp eventId");

// 2. path builder — how deep to descend into the response
out.push("earliestEdgeTime");
out.push("timestamp");        // right for a scalar, wrong for an object

// 3. parse arm — how to decode what is found there
terminal_val.as_i64()         // wrong once the field is an object

Updating (1) alone produced two successive runtime errors, one per missed site: Invalid response: `earliestEdgeTime` returned unexpected value type, then Invalid response: `timestamp` not a JSON object.

Note a shared field_name() helper would not catch this, since none of the three mistakes is a misspelled name — render_read_into has ~34 field literals and build_json_path ~137 path segments, but the bug class is the shape, not the string. The fix is to declare each terminal once (name + path depth + decoder) so "scalar int" versus "EventTime object" is a single decision the three arms derive from.

Raised in review: https://github.com/Pometry/Raphtory/pull/2675#discussion_r3804975599

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the remote client's ReadExpr and the render_read_into and build_json_path entry points named in the issue. Trace how terminal values are rendered, located, and decoded, then design a typed or builder-based structure that derives these shapes from one declaration. Done means invalid expression trees are unrepresentable and the duplicated terminal-shape logic and corresponding runtime validity checks are removed.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
database
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.