8000 feat: user predicates and aggregates (#180) by adityamukho · Pull Request #20 · project-minigraf/minigraf-java · GitHub
[go: up one dir, main page]

Skip to content

feat: user predicates and aggregates (#180) - #20

Merged
adityamukho merged 2 commits into
v3from
feat/180-udf-ffi
Oct 25, 2026
Merged

adityamukho merged 2 commits into
v3from
feat/180-udf-ffi

Conversation

@adityamukho
Copy link
Copy Markdown
Contributor

minigraf#180 PR 4 (plan steps 17–20): user-defined predicates and aggregates in the JVM binding.

  • Shim: src/lib.rs gets minigraf-binding-template#9's code unchanged: MiniGrafUdfError, the three with_foreign traits (MiniGrafPredicate, MiniGrafAggregate, MiniGrafAccumulator), registerPredicate/registerAggregate over the core's try_register_*, and handle locks that only clone the database. The template's Rust tests come with it.
  • Pin: core 7c8c5540 → 02243f16 (v3, after #757). The old pin already had #181 and #316; #306 needs no binding change.
  • Kotlin tests (UdfTest, 12): predicate; aggregate in :find and :over; MiniGrafUdfException.Failed and any other exception → MiniGrafException.Query with QRY-014 (exact message java.lang.IllegalStateException: own exception); failing step; bad Ref from finish; a predicate that queries the same db; cursors and prepared queries, including registration after prepare; QRY-014 inside a cursor; INT-040 on a duplicate name; two threads in one predicate at once (barrier).
  • Java test: lambda predicate, anonymous accumulator, an unchecked throw → QRY-014. The interfaces declare no checked exception, so Java can't throw MiniGrafUdfException.
  • Consumer contract: adult?, product, and a throw → QRY-014, from Java against the packaged jar.
  • README: a "User functions" section with Kotlin and Java examples, plus the §6.1 failures, lifecycle, threading, cost and re-entry text.

Verified on the bench machine: the new tests fail to compile against the old shim. With the new shim, cargo test (44), ./gradlew test (46) and consumer-test/run.sh local (6 contract + quickstart) pass.

Codex review: it said prepared queries capture the function registry at prepare time. That's not so (the core reads the snapshot when the executor opens), and a test now covers it. I declined its request to widen the consumer contract: the plan scopes it to one predicate and one aggregate.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Urda7FD9CYYoxdeGGJa11x

adityamukho and others added 2 commits October 25, 2026 11:35
MiniGrafPredicate, MiniGrafAggregate and MiniGrafAccumulator, implementable
from Kotlin and Java (lambdas for the one-method interfaces), and
MiniGrafDb.registerPredicate/registerAggregate over the core's
try_register_*. A throwing callback stops the query with QRY-014. Every
MiniGrafDb method locks its handle only to clone the database, so a
callback can call back into it. Shim code and Rust tests copied from
minigraf-binding-template#9; core pin 7c8c5540 -> 02243f16. Kotlin and
Java tests, consumer contract (predicate, aggregate, a throw is QRY-014),
README "User functions".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Urda7FD9CYYoxdeGGJa11x
@adityamukho
adityamukho merged commit 68de43c into v3 Oct 25, 2026
23 checks passed
@adityamukho
adityamukho deleted the feat/180-udf-ffi branch October 25, 2026 06:20
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.

1 participant

0