gustavodemorais commented on code in PR #28688:
URL: https://github.com/apache/flink/pull/28688#discussion_r3729863438
##########
flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/SqlJsonUtils.java:
##########
@@ -374,6 +390,70 @@ private static Object errorResultForJsonQuery(
}
}
+ /** Accepts a pre-parsed context from {@link #jsonParse}. */
+ public static Integer jsonLength(final JsonValueContext parsedInput) {
+ if (parsedInput == null || parsedInput.hasException()) {
+ return null;
+ }
+
+ // Whole document: a top-level JSON null literal counts as a scalar
(length 1).
+ return jsonLengthValue(parsedInput.obj);
+ }
+
+ /** Accepts a pre-parsed context from {@link #jsonParse}. */
+ public static Integer jsonLength(final JsonValueContext parsedInput, final
String pathSpec) {
+ // An empty path is ruled out up front because JsonPath rejects it
with an
+ // IllegalArgumentException instead of the InvalidPathException caught
below.
+ if (parsedInput == null || parsedInput.hasException() ||
pathSpec.isEmpty()) {
+ return null;
+ }
+
+ final Matcher matcher = JSON_PATH_BASE.matcher(pathSpec);
+ final boolean isExplicitLaxStrict = matcher.matches();
+ if (isExplicitLaxStrict) {
+ throw new TableRuntimeException(
+ String.format(
+ "JSON_LENGTH does not support the 'lax'/'strict'
path mode prefix (got: '%s'). "
+ + "Use a plain path such as '$.a.b'. To
check path existence or handle "
+ + "invalid input, use JSON_EXISTS or IS
JSON.",
+ pathSpec));
+ }
+ // JsonPath rejects a null root document, so a whole document that is
a JSON null literal
+ // has to be resolved here. Only the root path matches it, as a scalar
of length 1.
+ if (parsedInput.obj == null) {
+ return "$".equals(pathSpec) ? 1 : null;
+ }
+ final Object value;
+ try {
+ value = JsonPath.parse(parsedInput.obj,
JSON_PATH_LENGTH_CONFIG).read(pathSpec);
+ } catch (InvalidPathException e) {
+ // The path does not exist, or is not a valid path at all.
+ return null;
+ }
+
+ if (!JsonPath.isPathDefinite(pathSpec)) {
Review Comment:
"JsonPath.isPathDefinite(pathSpec)" This always yields the same result, the
path is always the same. However, this is currently being called for again for
every record in the pipeline. Move this to planning
```
Codegen can read literal - GeneratedExpression have field for it:
case class GeneratedExpression(
resultTerm: String, nullTerm: String, var code: String,
resultType: LogicalType, literalValue: Option[Any] = None)
Neighbours already do this. LikeCallGen.scala pull LIKE pattern this way.
JsonQueryCallGen and JsonValueCallGen pull their behaviors this way.
So in JsonCodeGenUtils:
final boolean definite =
!hasPath ||
JsonPath.isPathDefinite(operands.apply(1).literalValue().get().toString());
Compile happen once, at plan time. Then pass the answer down as plain
boolean:
String call = hasPath
? qualifyMethod(BuiltInMethods.JSON_TYPE_PATH())
+ "(" + parsed.varName + ", " + argTerms.apply(1) +
".toString(), " + definite + ")"
: qualifyMethod(BuiltInMethods.JSON_TYPE()) + "(" + parsed.varName +
")";
```
I think we are doing the same for json_length and should fix it there as well
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]