@@ -23,12 +23,13 @@ import org.apache.spark.sql.catalyst.expressions._
2323import org .apache .spark .sql .catalyst .expressions .aggregate .Sum
2424import org .apache .spark .sql .catalyst .expressions .json .StructsToJsonEvaluator
2525import org .apache .spark .sql .catalyst .expressions .objects .{Invoke , StaticInvoke }
26+ import org .apache .spark .sql .catalyst .expressions .url .ParseUrlEvaluator
2627import org .apache .spark .sql .catalyst .util .DateTimeUtils
2728import org .apache .spark .sql .internal .SQLConf
2829import org .apache .spark .sql .internal .types .StringTypeWithCollation
2930import org .apache .spark .sql .types .{ArrayType , BinaryType , BooleanType , DataTypes , MapType , StringType , TimeType }
3031
31- import org .apache .comet .CometConf
32+ import org .apache .comet .{ CometConf , CometExplainInfo }
3233import org .apache .comet .CometSparkSessionExtensions .withInfo
3334import org .apache .comet .expressions .{CometCast , CometEvalMode }
3435import org .apache .comet .serde .{CommonStringExprs , Compatible , ExprOuterClass , Incompatible , SupportLevel }
@@ -143,17 +144,25 @@ trait CometExprShim extends CommonStringExprs {
143144 val optExpr = scalarFunctionExprToProto(" width_bucket" , childExprs : _* )
144145 optExprWithInfo(optExpr, wb, wb.children: _* )
145146
146- // In Spark 4.0, StructsToJson is a RuntimeReplaceable whose replacement is
147- // Invoke(Literal(StructsToJsonEvaluator), "evaluate", ...). Reconstruct the
148- // original StructsToJson and recurse so support-level checks apply.
149- // ToTime (Spark 4.1) resolves to Invoke(Literal(ToTimeParser), "parse", TimeType(), ...).
147+ // In Spark 4.x, RuntimeReplaceable expressions (StructsToJson, ParseUrl) become
148+ // Invoke(Literal(Evaluator), "evaluate", ...). Reconstruct the original expression
149+ // and recurse so support-level checks apply.
150150 case i : Invoke =>
151151 (i.targetObject, i.functionName, i.arguments) match {
152152 case (Literal (evaluator : StructsToJsonEvaluator , _), " evaluate" , Seq (child)) =>
153153 exprToProtoInternal(
154154 StructsToJson (evaluator.options, child, evaluator.timeZoneId),
155155 inputs,
156156 binding)
157+ case (Literal (evaluator : ParseUrlEvaluator , _), " evaluate" , args) =>
158+ val parseUrl = ParseUrl (args, evaluator.failOnError)
159+ val result = exprToProtoInternal(parseUrl, inputs, binding)
160+ if (result.isEmpty) {
161+ parseUrl
162+ .getTagValue(CometExplainInfo .EXTENSION_INFO )
163+ .foreach(reasons => i.setTagValue(CometExplainInfo .EXTENSION_INFO , reasons))
164+ }
165+ result
157166 case (Literal (parser : ToTimeParser , _), " parse" , args)
158167 if i.dataType.isInstanceOf [TimeType ] && parser.fmt.isEmpty && args.size == 1 =>
159168 val childExprs = args.map(exprToProtoInternal(_, inputs, binding))
0 commit comments