diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/regexpExpressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/regexpExpressions.scala index 6ff6dc729795d..c6fb6c95e5d31 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/regexpExpressions.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/regexpExpressions.scala @@ -152,8 +152,6 @@ case class Like(left: Expression, right: Expression, escapeChar: Char = '\\') """) } } else { - val pattern = ctx.freshName("pattern") - val rightStr = ctx.freshName("rightStr") // We need double escape to avoid org.codehaus.commons.compiler.CompileException. // '\\' will cause exception 'Single quote must be backslash-escaped in character literal'. // '\"' will cause exception 'Line break in literal not allowed'. @@ -162,10 +160,17 @@ case class Like(left: Expression, right: Expression, escapeChar: Char = '\\') } else { escapeChar } + val rightStr = ctx.freshName("rightStr") + val pattern = ctx.addMutableState(patternClass, "pattern") + val lastRightStr = ctx.addMutableState(classOf[String].getName, "lastRightStr") + nullSafeCodeGen(ctx, ev, (eval1, eval2) => { s""" String $rightStr = $eval2.toString(); - $patternClass $pattern = $patternClass.compile($escapeFunc($rightStr, '$newEscapeChar')); + if (!$rightStr.equals($lastRightStr)) { + $pattern = $patternClass.compile($escapeFunc($rightStr, '$newEscapeChar')); + $lastRightStr = $rightStr; + } ${ev.value} = $pattern.matcher($eval1.toString()).matches(); """ }) @@ -240,11 +245,16 @@ case class RLike(left: Expression, right: Expression) extends StringRegexExpress } } else { val rightStr = ctx.freshName("rightStr") - val pattern = ctx.freshName("pattern") + val pattern = ctx.addMutableState(patternClass, "pattern") + val lastRightStr = ctx.addMutableState(classOf[String].getName, "lastRightStr") + nullSafeCodeGen(ctx, ev, (eval1, eval2) => { s""" String $rightStr = $eval2.toString(); - $patternClass $pattern = $patternClass.compile($rightStr); + if (!$rightStr.equals($lastRightStr)) { + $pattern = $patternClass.compile($rightStr); + $lastRightStr = $rightStr; + } ${ev.value} = $pattern.matcher($eval1.toString()).find(0); """ })