Skip to content

fix(reasoning): support Lakebase/Postgres dialect and rebuild class URIs against the current Base URI - #174

Open
benoitcayladbx wants to merge 1 commit into
0.9.0from
fix/reasoning-lakebase-dialect-and-stale-uri
Open

benoitcayladbx wants to merge 1 commit into
0.9.0from
fix/reasoning-lakebase-dialect-and-stale-uri

Conversation

@benoitcayladbx

Copy link
Copy Markdown
Collaborator

Reopened against 0.9.0 after develop was deleted. GitHub cannot reopen #146 (closed PR + missing base), so this is a successor of #146 with the same commits. Original author: @jeremiaspf. Please rebase onto current 0.9.0 before review — expect conflicts.


What

Two independent problems in the four reasoning-rule engines (Aggregate Rules, Decision Tables, SPARQL Rules, SWRL), found while running 0.7.1 in production:

1. Rules stop finding their target class after the domain is re-based.
When a domain's Base URI changes after a class already exists, that class can be left with a stale uri (the old Base URI) in its stored field. AggregateRuleEngine, DecisionTableEngine, SPARQLRuleEngine and SWRLEngine all trusted that stored uri as-is to find a rule's target/result class. All four now reconstruct the URI from the class's local name against the domain's current Base URI instead, matching what the rest of the codebase already does in this situation.

2. Numeric comparisons fail entirely against Lakebase (Postgres).
SQLHelpers's numeric-cast helper (used by all four engines wherever a rule compares a value numerically — an Aggregate Rule threshold, a Decision Table numeric condition) used TRY_CAST, which doesn't exist in PostgreSQL. Any such rule failed outright once the graph was stored in Lakebase. SQLHelpers.to_number() now takes a dialect parameter; on "postgres" it emits a CASE WHEN <regex validates numeric> THEN CAST … ELSE NULL END instead.

Two smaller, engine-specific fixes rode along because they touch the same functions:

  • AggregateRuleEngine: inferred triples were only computed when materialize=True. An Aggregate Rule with a Result Entity configured but previewed (Run, not materialized) always showed 0 inferred triples even with matching rows. Now computed whenever a Result Entity is configured, consistent with the other rule engines.
  • DecisionTableEngine: an input column left without an associated property (blank mapping) generated a SQL condition referencing a table that was never joined, raising missing FROM-clause entry. That column is now skipped instead, and the rest of the row still evaluates.

Why

All four are silent-failure modes: a rule that looks correctly configured in the UI either returns nothing or throws a raw SQL error, with no obvious link back to "the domain was renamed" or "the graph lives in Lakebase."

How to test

  1. Create a domain, add a class, change the domain's Base URI, then create an Aggregate Rule / Decision Table / SPARQL Rule / SWRL rule targeting that class — before this fix, the rule returns 0 results/inferred triples; after, it finds the class normally.
  2. Same setup but with the triple store on Lakebase, and a rule with a numeric threshold/condition — before this fix, running the rule raises a SQL error; after, it evaluates correctly.
  3. An Aggregate Rule with a Result Entity, clicked "Run" without materializing — before, 0 inferred triples shown even with matching data; after, the preview shows them.
  4. A Decision Table with one input column left unmapped — before, running it raises missing FROM-clause entry; after, that column is ignored and the rest of the table evaluates.

Happy to add/adjust automated tests for any of these if that's useful — wanted to get the report and the fix out first rather than block on writing a full suite against your test fixtures.

…RIs against the current Base URI

SQLHelpers.to_number() gains a dialect parameter: on Lakebase (Postgres) it
emits a CASE/regex guard instead of TRY_CAST, which does not exist in
PostgreSQL. AggregateRuleEngine and DecisionTableEngine now detect the
triple-store backend and pass the right dialect through, so numeric
comparisons in Aggregate Rules and Decision Tables work against both
Databricks SQL and Lakebase.

AggregateRuleEngine, DecisionTableEngine, SPARQLRuleEngine and SWRLEngine
all reconstruct a rule's target class URI from its local name against the
domain's *current* Base URI instead of trusting the class's stored uri
field, which goes stale after the domain is re-based (Base URI changed
after the class already existed). Without this, a rule silently stopped
finding its target class and returned zero results/inferred triples.

AggregateRuleEngine also now computes inferred triples whenever a rule has
a Result Entity configured, not only when materialize=True — previously,
clicking "Run" (preview, no materialize) on such a rule always showed 0
inferred triples even when matching rows existed.

DecisionTableEngine additionally ignores an input column left without an
associated property (blank mapping) instead of generating a SQL condition
that references a table never joined, which raised a "missing FROM-clause
entry" error.
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.

2 participants