Skip to content

Commit a123c6d

Browse files
committed
Refactor RegexParser to handle unsupported regex groups
Consolidate the per-type unsupported-group handling in CudfRegexTranspiler so an unexpected group type falls back to the CPU rather than crashing the query. Also cover the empty lookaround forms, which Java accepts. Signed-off-by: Igor Peshansky <ipeshansky@nvidia.com>
1 parent 6e300e7 commit a123c6d

2 files changed

Lines changed: 29 additions & 35 deletions

File tree

sql-plugin/src/main/scala/com/nvidia/spark/rapids/RegexParser.scala

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,10 @@ class RegexParser(pattern: String) {
203203
consumeExpected('>')
204204
RegexGroup.Named(name)
205205
case _ => throw new RegexUnsupportedException(
206-
s"Unexpected character after '<' in group", Some(pos-1))
206+
"Unexpected character after '<' in group", Some(pos-1))
207207
}
208208
case '<' => throw new RegexUnsupportedException(
209-
s"Pattern may not end with trailing '<' in group", Some(pos-1))
209+
"Pattern may not end with trailing '<' in group", Some(pos-1))
210210
}
211211
} else {
212212
RegexGroup.Capturing
@@ -252,8 +252,7 @@ class RegexParser(pattern: String) {
252252
}
253253
}
254254
case None =>
255-
throw new RegexUnsupportedException(
256-
s"Unclosed character class", Some(pos))
255+
throw new RegexUnsupportedException("Unclosed character class", Some(pos))
257256
}
258257
}
259258

@@ -325,7 +324,7 @@ class RegexParser(pattern: String) {
325324
}
326325
}
327326
if (!characterClassComplete) {
328-
throw new RegexUnsupportedException(s"Unclosed character class", Some(pos))
327+
throw new RegexUnsupportedException("Unclosed character class", Some(pos))
329328
}
330329
characterClass
331330
}
@@ -1592,31 +1591,7 @@ class CudfRegexTranspiler(mode: RegexMode) {
15921591
}
15931592
RegexChoice(ll, rr)
15941593

1595-
case g @ RegexGroup(RegexGroup.PositiveLookahead |
1596-
RegexGroup.NegativeLookahead |
1597-
RegexGroup.PositiveLookbehind |
1598-
RegexGroup.NegativeLookbehind |
1599-
RegexGroup.Independent |
1600-
RegexGroup.Named(_), _) =>
1601-
val msg = g.groupType match {
1602-
case RegexGroup.PositiveLookahead =>
1603-
"Positive lookahead groups are not supported"
1604-
case RegexGroup.NegativeLookahead =>
1605-
"Negative lookahead groups are not supported"
1606-
case RegexGroup.PositiveLookbehind =>
1607-
"Positive lookbehind groups are not supported"
1608-
case RegexGroup.NegativeLookbehind =>
1609-
"Negative lookbehind groups are not supported"
1610-
case RegexGroup.Independent =>
1611-
"Independent groups are not supported"
1612-
case RegexGroup.Named(_) =>
1613-
"Named capture groups are not supported"
1614-
case _ => // unreachable
1615-
throw new IllegalStateException(s"Unhandled group type: ${g.groupType}")
1616-
}
1617-
throw new RegexUnsupportedException(msg, g.position)
1618-
1619-
case RegexGroup(groupType, term) =>
1594+
case g @ RegexGroup(RegexGroup.Capturing | RegexGroup.NonCapturing, term) =>
16201595
term match {
16211596
case RegexSequence(parts) =>
16221597
parts.foreach { part =>
@@ -1642,7 +1617,26 @@ class CudfRegexTranspiler(mode: RegexMode) {
16421617
}
16431618
case _ =>
16441619
}
1645-
RegexGroup(groupType, rewrite(term, replacement, None, flags))
1620+
RegexGroup(g.groupType, rewrite(term, replacement, None, flags))
1621+
1622+
case g @ RegexGroup(_, _) =>
1623+
val msg = g.groupType match {
1624+
case RegexGroup.PositiveLookahead =>
1625+
"Positive lookahead groups are not supported"
1626+
case RegexGroup.NegativeLookahead =>
1627+
"Negative lookahead groups are not supported"
1628+
case RegexGroup.PositiveLookbehind =>
1629+
"Positive lookbehind groups are not supported"
1630+
case RegexGroup.NegativeLookbehind =>
1631+
"Negative lookbehind groups are not supported"
1632+
case RegexGroup.Independent =>
1633+
"Independent groups are not supported"
1634+
case RegexGroup.Named(_) =>
1635+
"Named capture groups are not supported"
1636+
case _ =>
1637+
s"Unknown group type: ${g.groupType}"
1638+
}
1639+
throw new RegexUnsupportedException(msg, g.position)
16461640

16471641
case other =>
16481642
throw new RegexUnsupportedException(s"Unhandled expression in transpiler: $other",

tests/src/test/scala/com/nvidia/spark/rapids/RegularExpressionTranspilerSuite.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,25 +159,25 @@ class RegularExpressionTranspilerSuite extends AnyFunSuite {
159159
}
160160

161161
test("cuDF does not support positive or negative lookaround") {
162-
val posLookaheadPatterns = Seq("a(?=b)", "a(?=b)c?")
162+
val posLookaheadPatterns = Seq("a(?=b)", "a(?=b)c?", "(?=)")
163163
posLookaheadPatterns.foreach(pattern =>
164164
assertUnsupported(pattern, RegexFindMode,
165165
"Positive lookahead groups are not supported")
166166
)
167167

168-
val negLookaheadPatterns = Seq("a(?!b)", "a(?!b)c?")
168+
val negLookaheadPatterns = Seq("a(?!b)", "a(?!b)c?", "(?!)")
169169
negLookaheadPatterns.foreach(pattern =>
170170
assertUnsupported(pattern, RegexFindMode,
171171
"Negative lookahead groups are not supported")
172172
)
173173

174-
val posLookbehindPatterns = Seq("a(?<=b)", "a(?<=b)c?")
174+
val posLookbehindPatterns = Seq("a(?<=b)", "a(?<=b)c?", "(?<=)")
175175
posLookbehindPatterns.foreach(pattern =>
176176
assertUnsupported(pattern, RegexFindMode,
177177
"Positive lookbehind groups are not supported")
178178
)
179179

180-
val negLookbehindPatterns = Seq("a(?<!b)", "a(?<!b)c?")
180+
val negLookbehindPatterns = Seq("a(?<!b)", "a(?<!b)c?", "(?<!)")
181181
negLookbehindPatterns.foreach(pattern =>
182182
assertUnsupported(pattern, RegexFindMode,
183183
"Negative lookbehind groups are not supported")

0 commit comments

Comments
 (0)