raminqaf commented on code in PR #29617:
URL: https://github.com/apache/flink/pull/29617#discussion_r4401696692


##########
flink-table/flink-table-common/src/main/java/org/apache/flink/table/utils/SimplePath.java:
##########
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.utils;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.util.Preconditions;
+
+import javax.annotation.Nullable;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+/**
+ * A path that points at exactly one place in a value, such as {@code 
$.user.email} or {@code
+ * $['items'][0]}.
+ *
+ * <p>The syntax is the part of the JSON functions' path syntax that names a 
single place: no
+ * wildcards, filters, slices, negative indices, functions or {@code lax} and 
{@code strict} modes.
+ * Every path that this class accepts means the same in the JSON functions. A 
path starts with
+ * {@code $}, the whole value, followed by any number of steps:
+ *
+ * <ul>
+ *   <li>{@code .name} is a field. The name cannot contain whitespace or one 
of the characters
+ *       {@code . [ ] ( ) * ' " \}.
+ *   <li>{@code ['name']} and {@code ["name"]} are a field with any name. 
Inside the quotes, a
+ *       backslash followed by a backslash or a quote stands for that 
character.
+ *   <li>{@code [n]} is the array element at the 0-based index {@code n}.
+ * </ul>
+ *
+ * <p>Trailing spaces are ignored, as in the JSON functions, so a space-padded 
{@code CHAR(n)} path
+ * works.
+ */
+@Internal
+public final class SimplePath implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String SYNTAX =
+            "A path is '$' followed by the steps .name, ['name'], [\"name\"] 
or [index], "
+                    + "without wildcards, filters, slices, negative indices or 
functions. "
+                    + "Use brackets for a name that has whitespace or one of 
the characters "
+                    + ". [ ] ( ) * ' \" \\ in it.";
+
+    private static final String NAME_STOP_CHARACTERS = ".[]()*'\"\\";
+
+    private static final Pattern PATH_MODE_PREFIX =
+            Pattern.compile("\\s*(strict|lax)\\s.*", Pattern.CASE_INSENSITIVE 
| Pattern.DOTALL);
+
+    private final String path;
+
+    private final List<Step> steps;
+
+    private SimplePath(final String path, final List<Step> steps) {
+        this.path = path;
+        this.steps = steps;
+    }
+
+    /**
+     * Parses a path.
+     *
+     * @throws IllegalArgumentException if the path is malformed or uses 
syntax that can point at
+     *     more than one place
+     */
+    public static SimplePath parse(final String path) {
+        Preconditions.checkNotNull(path, "Path must not be null.");
+        return new Parser(path).parse();
+    }
+
+    /** Returns the steps after {@code $}, so the root path has none. */
+    public List<Step> getSteps() {
+        return steps;
+    }
+
+    @Override
+    public String toString() {
+        return path;
+    }
+
+    // 
--------------------------------------------------------------------------------------------
+
+    /** A step to a field of an object or to an element of an array. */
+    @Internal
+    public static final class Step implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        private final @Nullable String fieldName;
+
+        private final int index;
+
+        private Step(final @Nullable String fieldName, final int index) {
+            this.fieldName = fieldName;
+            this.index = index;
+        }
+
+        public static Step field(final String fieldName) {
+            return new Step(Preconditions.checkNotNull(fieldName), -1);
+        }
+
+        public static Step index(final int index) {
+            Preconditions.checkArgument(index >= 0, "Index must not be 
negative.");

Review Comment:
   Yes. Only the parser creates steps. It reads an index from digits only and 
rejects one above `Integer.MAX_VALUE `with a `ValidationException`, so this 
precondition can't fail on user input. 
   
   I made `field()` and `index()` package-private, so only the parser and its 
test can call them.



-- 
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]

Reply via email to