Skip to content

[ISSUE-358] Implement ISO-GQL labeled predicate - #824

Merged
yaozhongq merged 2 commits into
apache:masterfrom
yyyCode:feat/issue-358-labeled-predicate
Aug 10, 2026
Merged

[ISSUE-358] Implement ISO-GQL labeled predicate#824
yaozhongq merged 2 commits into
apache:masterfrom
yyyCode:feat/issue-358-labeled-predicate

Conversation

@yyyCode

@yyyCode yyyCode commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Closes #358.

Implements the ISO-GQL <labeled predicate> (ISO/IEC 39075 Section 19.9), which tests whether a graph element (vertex or edge) carries a given label.

Following the pattern of the already-merged source/destination predicate (#366 / PR #675), this is implemented as built-in UDFs rather than a grammar change:

  • IS_LABELED(element, label) — returns TRUE if the vertex/edge has the given label, FALSE otherwise.
  • IS_NOT_LABELED(element, label) — the negation.

Both follow ISO-GQL three-valued logic: a null element or null label yields Unknown (null). A non-graph-element first operand raises a clear IllegalArgumentException.

Files:

  • LabeledPredicateFunctions (geaflow-dsl-common) — shared static logic.
  • IsLabeled / IsNotLabeled (geaflow-dsl-plan) — UDFs delegating to the logic, registered in BuildInSqlFunctionTable.

Example:

MATCH (a) -[e]-> (b)
WHERE IS_LABELED(a, 'person')
RETURN a, e, b

How was this PR tested?

  • Tests have Added for the changes

  • Production environment verified

  • LabeledPredicateFunctionsTest (geaflow-dsl-common): unit-tests the logic directly — vertex/edge label matching, negation, three-valued null handling, and rejection of non-graph-element operands. Passes 5/5 locally.

  • GQLLabeledPredicateTest (geaflow-dsl-runtime): an end-to-end .sql/.txt case over the modern graph, exercising IS_LABELED/IS_NOT_LABELED on both vertices and edges. Expected outputs were computed by hand from the graph data (not copied from program output).

mvn checkstyle:check reports 0 violations across the three touched modules.

Note: the runtime end-to-end test could not be executed on my local Windows machine because Hadoop's winutils.exe is required to write the file sink (the existing GQLSourceDestinationTest fails locally for the same reason). It is expected to run on the Linux CI. The predicate logic itself is fully covered by the platform-independent unit test.

Adds the ISO-GQL <labeled predicate> (ISO/IEC 39075 Section 19.9), which
tests whether a graph element (vertex or edge) carries a given label.

Following the pattern of the already-merged source/destination predicate
(apache#366), this is implemented as built-in UDFs rather than a grammar change:

- `IS_LABELED(element, label)` — TRUE if the element has the label.
- `IS_NOT_LABELED(element, label)` — the negation.

Both follow ISO-GQL three-valued logic: a null element or null label
yields Unknown (null). The shared logic lives in
`LabeledPredicateFunctions` (geaflow-dsl-common); the UDFs delegate to it
and are registered in `BuildInSqlFunctionTable`.

Tests:
- `LabeledPredicateFunctionsTest` (geaflow-dsl-common) unit-tests the
  logic directly: vertex/edge labels, negation, three-valued null
  handling, and rejection of non-graph-element operands.
- `GQLLabeledPredicateTest` (geaflow-dsl-runtime) is an end-to-end
  `.sql`/`.txt` case over the modern graph; expected outputs were
  computed by hand from the graph data.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yaozhongq
yaozhongq self-requested a review August 3, 2026 07:58

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This package is intended for general-purpose interfaces. There is no need to split the current function into a separate Func; I suggest placing it directly into the UDF.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, thanks. Fixed in 5c65fc8: I moved the label-matching and three-valued-null logic (plus a private getLabel helper) directly into IsLabeled, and IsNotLabeled now delegates to an IsLabeled instance and negates the result, so label extraction stays in one place. Removed LabeledPredicateFunctions and its test from geaflow-dsl-common, and moved the unit test into geaflow-dsl-plan as LabeledPredicateTest (same udf/table/other package as the UDFs, matching PropertyExistsTest), testing through the UDF eval methods.

Note: the existing merged predicates (IsSourceOf/PropertyExists) still use the split helper pattern this PR was originally modeled on, so the labeled predicate is now self-contained and diverges from them. Happy to align those too in a follow-up if you would prefer consistency.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review @yaozhongq. Confirmed on the latest commit: LabeledPredicateFunctions is gone from geaflow-dsl-common, the label-matching + three-valued-null logic (and the getLabel helper) now lives directly in IsLabeled, and IsNotLabeled delegates to an IsLabeled instance so label extraction stays in one place. The unit test moved to geaflow-dsl-plan as LabeledPredicateTest (same package as the UDFs, matching PropertyExistsTest) and passes 5/5 locally. PTAL when you get a chance.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, looks great!

The geaflow-dsl-common/function package is for general-purpose interfaces,
so the labeled predicate logic should live in the UDFs rather than a separate
helper class there.

- Inline the label-matching and three-valued-null logic (plus a private
  getLabel helper) directly into IsLabeled; IsNotLabeled delegates to an
  IsLabeled instance and negates, keeping label extraction in one place.
- Remove LabeledPredicateFunctions and its test from geaflow-dsl-common.
- Move the unit test to geaflow-dsl-plan as LabeledPredicateTest (same
  udf/table/other package as the UDFs, matching PropertyExistsTest), testing
  through the UDF eval methods.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@yaozhongq yaozhongq left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@yaozhongq
yaozhongq merged commit 3f73eb5 into apache:master Aug 10, 2026
2 checks passed
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.

Added implementation of standard ISO-GQL syntax(1):labeled predicate

2 participants