Skip to content

fix: allow chaining with fixed-length patterns#771

Merged
SemyonSinchenko merged 3 commits into
graphframes:mainfrom
goungoun:main
Jan 25, 2026
Merged

fix: allow chaining with fixed-length patterns#771
SemyonSinchenko merged 3 commits into
graphframes:mainfrom
goungoun:main

Conversation

@goungoun
Copy link
Copy Markdown
Contributor

@goungoun goungoun commented Jan 9, 2026

What changes were proposed in this pull request?

This PR removes the limitation from a fixed-length pattern. It should work with chaining with other patterns such as:
(u)-[*2]->(v);(v)-[]->(k), (u)-[]->(v);(v)-[*2]->(k);(a)-[*1]->(b);(b)-[*2]->(c);(c)-[*3]->(d)

Why are the changes needed?

The current version cannot parse a chained pattern when it is with a fixed-length pattern.

image

Error:

scala> g.find("(a)-[*2]->(b);(b)-[]->(c)").where("a.id == 0").show()
org.graphframes.InvalidParseException: Failed to parse bad motif string: '(a)-[*2]->(b);(b)-[]->(c)'.  Returned message: end of input expected
  at org.graphframes.pattern.Pattern$.parse(patterns.scala:83)
  at org.graphframes.GraphFrame.findAugmentedPatterns(GraphFrame.scala:520)
  at org.graphframes.GraphFrame.find(GraphFrame.scala:515)
  ... 42 elided

Expected:

+---------+---------+---------+---------+
|        a|     _ab1|        b|        c|
+---------+---------+---------+---------+
|{0, a, f}|{1, b, m}|{2, c, m}|{0, a, f}|
|{0, a, f}|{1, b, m}|{2, c, m}|{3, d, f}|
|{0, a, f}|{1, b, m}|{0, a, f}|{1, b, m}|
+---------+---------+---------+---------+

How does it work?

The fixed-length vertex generation logic is moved to the query rewrite phase. The naming rule for generating interim vertexes has changed from _v1, _v2, _v3 to _uv1, _uv2, _uv3, where the names are derived by combining the source and target vertex names u and v. This behavior change is inevitable to prevent duplication. For example, in the pattern (b)-[*2]->(c);(c)-[*3]->(d) _v1 should not be generated twice, as it would result in duplicated column name. Instead, _bc and _cd will be generated.

Before: Parser

val midVertices = (1 until hop).map(i => NamedVertex(s"_v$i"))

After: Pattern Rewrite

val midVertices = (1 until hop).map(i => s"_${src}${dst}${i}")

@goungoun goungoun changed the title fix: allow chaining with fixed-length patterns [WIP] fix: allow chaining with fixed-length patterns Jan 9, 2026
@goungoun goungoun marked this pull request as draft January 9, 2026 11:54
@goungoun
Copy link
Copy Markdown
Contributor Author

goungoun commented Jan 23, 2026

The fix does not cover for a undirected fixed length pattern such as (u)-[*2]-(v);(v)-[]->(k). It still fails because it does not support (u)-[*2]-(v). The workaround is to rewrite (u)-[*2..2]-(v), but it does not support chaining(u)-[*2..2]-(v);(v)-[]->(k). I left it as a separate issue.

@goungoun goungoun changed the title [WIP] fix: allow chaining with fixed-length patterns fix: allow chaining with fixed-length patterns Jan 23, 2026
@goungoun goungoun marked this pull request as ready for review January 23, 2026 15:24
*/
private[graphframes] def rewriteFixedLengthPattern(patterns: String): String = {
val fixedLengthPattern =
"""(!*)\(([a-zA-Z0-9_]*)\)-\[([a-zA-Z0-9_]*)\*([0-9]+)\]->\(([a-zA-Z0-9_]*)\)""".r
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why (!*)? Is the !!!!!... a valid pattern? Should it be (!?)?

Copy link
Copy Markdown
Contributor Author

@goungoun goungoun Jan 25, 2026

Choose a reason for hiding this comment

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

@SemyonSinchenko, Good point. There is no use to rewrite negation of the negation pattern. It will be failing from the parser eventually. I do not have the intention to support !!!!!. I changed the pattern from (!*) to (!?). Thanks!

Copy link
Copy Markdown
Collaborator

@SemyonSinchenko SemyonSinchenko left a comment

Choose a reason for hiding this comment

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

Nice work, thanks @goungoun !

@SemyonSinchenko SemyonSinchenko merged commit fdfaa07 into graphframes:main Jan 25, 2026
5 checks passed
@goungoun
Copy link
Copy Markdown
Contributor Author

Thank you @SemyonSinchenko

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants