chucheng92 commented on code in PR #3320:
URL: https://github.com/apache/calcite/pull/3320#discussion_r1291604326


##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -4107,6 +4113,93 @@ public static List arrayExcept(List list1, List list2) {
     return new ArrayList<>(result);
   }
 
+  /** Support the ARRAY_INSERT function. */
+  public static @Nullable List arrayInsert(List baselist, Object pos, Object 
val) {
+    if (baselist == null || pos == null) {
+      return null;
+    }
+    int posInt = (int) pos;
+    Object[] baseArray = baselist.toArray();
+    if (posInt == 0) {
+      throw new IllegalArgumentException("The index 0 is invalid. "
+          + "An index shall be either < 0 or > 0 (the first element has index 
1)");
+    }
+
+    boolean usePositivePos = posInt > 0;
+
+    if (usePositivePos) {
+      int newArrayLength = Math.max(baseArray.length + 1, posInt);
+
+      if (newArrayLength > MAX_ARRAY_LENGTH) {
+        throw new IndexOutOfBoundsException(
+            String.format(Locale.ROOT, "The new array length %s exceeds the 
allowed limit.",
+                newArrayLength));
+      }
+
+      Object[] newArray = new Object[newArrayLength];
+
+      int posIndex = posInt - 1;
+      if (posIndex < baseArray.length) {
+        System.arraycopy(baseArray, 0, newArray, 0, posIndex);
+        newArray[posIndex] = val;
+        System.arraycopy(baseArray, posIndex, newArray, posIndex + 1, 
baseArray.length - posIndex);
+      } else {
+        System.arraycopy(baseArray, 0, newArray, 0, baseArray.length);
+        newArray[posIndex] = val;
+      }
+
+      return Arrays.asList(newArray);
+    } else {
+      int posIndex = posInt;
+
+      boolean newPosExtendsArrayLeft = baseArray.length + posIndex < 0;
+
+      if (newPosExtendsArrayLeft) {
+        // special case, if the new position is negative but larger than the 
current array size
+        // place the new item at start of array, place the current array 
contents at the end
+        // and fill the newly created array elements in middle with a null
+        int newArrayLength = -posIndex + 1;

Review Comment:
   thanks for reminding me. however, we can not use
   `int newArrayLength = Integer.MAX_VALUE - (Integer.MAX_VALUE + posIndex);`
   if posIndex = Integer.MIN_VALUE, it will be 
   `int newArrayLength = Integer.MAX_VALUE + 1;` and overflow.
   
   In fact, pos cannot exceed the maximum array limit, we can check in advance 
just like pos cannot be 0. and -pos will not overflow in subsequent code logic.
   
   I have updated the PR and add overflow test cases. If you are free, PTAL. 



##########
core/src/main/java/org/apache/calcite/util/BuiltInMethod.java:
##########
@@ -658,6 +658,7 @@ public enum BuiltInMethod {
   ARRAYS_OVERLAP(SqlFunctions.class, "arraysOverlap", List.class, List.class),
   ARRAYS_ZIP(SqlFunctions.class, "arraysZip", List.class, List.class),
   SORT_ARRAY(SqlFunctions.class, "sortArray", List.class, boolean.class),
+  ARRAY_INSERT(SqlFunctions.class, "arrayInsert", List.class, Integer.class, 
Object.class),

Review Comment:
   fixed



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