JSON array manipulation functions

Updated at:
Copy as MD

Lindorm SQL provides JSON_ARRAY_INSERT and JSON_ARRAY_APPEND to insert and append values in JSON arrays.

Function overview

JSON_ARRAY_INSERT

Inserts a value at a specified position in a JSON array. The path must point to an array element, such as $[0] or $.a[0].

Note

Requires wide table engine version 2.8.6.5 or later.

Syntax:

JSON_ARRAY_INSERT(json_doc, path, value[, path2, value2] ...)

Parameters:

  • json_doc: The JSON document to modify (as a string).

  • path: The insertion position. Must point to an array element (such as $[0] or $.a[0]).

  • value: The value to insert.

  • You can specify multiple path-value pairs for a batch insert.

Return value: The modified JSON document as a string.

JSON_ARRAY_APPEND

Appends one or more values to the end of specified arrays within a JSON document.

Note

Requires wide table engine version 2.8.6.5 or later.

Syntax:

JSON_ARRAY_APPEND(json_doc, path, value[, path2, value2] ...)

Parameters:

  • json_doc: The JSON document to modify (as a string).

  • path: The target array path, such as $, $[1], or $.hobby.

  • value: The value to append.

  • You can specify multiple path-value pairs for a batch append.

Return value: The modified JSON document as a string.

Usage examples

Basic operations

-- Create a table
CREATE TABLE t (id INT, c2 JSON, tags JSON, PRIMARY KEY(id)) 'CONSISTENCY' = 'strong';

-- Initial data
INSERT INTO t(id, tags, c2) VALUES
  (1, '["a","b","c"]',               '[1,[2,3]]'),
  (2, '[1,2,3]',                      '[1,2,3]'),
  (3, NULL,                           '"hello"'),
  (4, NULL,                           '{"key":"value"}'),
  (5, NULL,                           '{"name":"Tim","hobby":["car"]}'),
  (6, NULL,                           '{"field":"value"}'),
  (7, NULL,                           '{"tags":["java"],"categories":["tech"]}');

-- Insert at a specified position, shifting subsequent elements to the right
UPDATE t SET tags = JSON_ARRAY_INSERT(tags, '$[0]', 'first') WHERE id = 1;
-- Original: ["a","b","c"], Result: ["first","a","b","c"]

-- Append to the end of the array
UPDATE t SET tags = JSON_ARRAY_APPEND(tags, '$', 'last') WHERE id = 2;
-- Original: [1,2,3], Result: [1,2,3,"last"]

-- Operate on a nested array (paths support arbitrary depth)
UPDATE t SET c2 = JSON_ARRAY_INSERT(c2, '$[1][0]', 'x') WHERE id = 1;
-- Original: [1,[2,3]], Result: [1,["x",2,3]]

-- Append to an array within an object
UPDATE t SET c2 = JSON_ARRAY_APPEND(c2, '$.hobby', 'food') WHERE id = 5;
-- Original: {"name":"Tim","hobby":["car"]}, Result: {"name":"Tim","hobby":["car","food"]}

-- INSERT: Fails if the path does not point to an array.
UPDATE t SET c2 = JSON_ARRAY_INSERT(c2, '$[0]', 'x') WHERE id = 3;
-- Original: "hello" (scalar), Error: Path does not point to array

UPDATE t SET c2 = JSON_ARRAY_INSERT(c2, '$[0]', 'x') WHERE id = 4;
-- Original: {"key":"value"} (object), Error: Path does not point to array

-- APPEND: Wraps a non-array node in an array and then appends the new value.
UPDATE t SET c2 = JSON_ARRAY_APPEND(c2, '$', 'world') WHERE id = 3;
-- Original: "hello", Result: ["hello","world"]

UPDATE t SET c2 = JSON_ARRAY_APPEND(c2, '$', 'item') WHERE id = 4;
-- Original: {"key":"value"}, Result: [{"key":"value"},"item"]

-- Convert a scalar field within an object to an array in place
UPDATE t SET c2 = JSON_ARRAY_APPEND(c2, '$.field', 'new') WHERE id = 6;
-- Original: {"field":"value"}, Result: {"field":["value","new"]}

Batch operations

Each path-value pair executes sequentially — the result of each step becomes the input for the next, and indices reflect the current array state:

-- Batch insert: Indices are re-evaluated after each insertion.
UPDATE t SET c2 = JSON_ARRAY_INSERT(c2, '$[0]', 'first', '$[3]', 'middle', '$[6]', 'last') WHERE id = 2;
-- Original: [1,2,3], Result: ["first",1,2,"middle",3,"last"]

-- Multiple insertions at the same position: Later insertions appear first.
UPDATE t SET c2 = JSON_ARRAY_INSERT(c2, '$[0]', 'a', '$[0]', 'b') WHERE id = 2;
-- Original: [1,2,3], Result: ["b","a",1,2,3]

-- Batch append to multiple sub-arrays
UPDATE t SET c2 = JSON_ARRAY_APPEND(c2, '$.tags', 'sql', '$.tags', 'python', '$.categories', 'db') WHERE id = 7;
-- Original: {"tags":["java"],"categories":["tech"]}
-- Result: {"tags":["java","sql","python"],"categories":["tech","db"]}

Index out of bounds

If the index exceeds the array length, the value is appended to the end. This matches MySQL behavior.

UPDATE t SET c2 = JSON_ARRAY_INSERT(c2, '$[100]', 'x') WHERE id = 2;
-- Original: [1,2,3], Result: [1,2,3,"x"]

Parameterization with PreparedStatement

You can use the ? placeholder for both the path and value parameters.

// Initial data for id=1: c2 = ["a","inserted","b","c","appended"]

// JSON_ARRAY_INSERT: Insert at position $[2]
PreparedStatement pstmt = conn.prepareStatement(
    "UPDATE t SET c2 = JSON_ARRAY_INSERT(c2, ?, ?) WHERE id = ?");
pstmt.setString(1, "$[2]");
pstmt.setString(2, "prep_insert");
pstmt.setInt(3, 1);
pstmt.executeUpdate();
// Result: ["a","inserted","prep_insert","b","c","appended"]

// JSON_ARRAY_APPEND: Append to the end of the array
pstmt = conn.prepareStatement(
    "UPDATE t SET c2 = JSON_ARRAY_APPEND(c2, ?, ?) WHERE id = ?");
pstmt.setString(1, "$");
pstmt.setString(2, "prep_append");
pstmt.setInt(3, 1);
pstmt.executeUpdate();
// Result: ["a","inserted","prep_insert","b","c","appended","prep_append"]

Node type and NULL handling

Scenario

JSON_ARRAY_INSERT

JSON_ARRAY_APPEND

Column is NULL

Creates an empty array and inserts the value.

Creates an empty array and appends the value.

Scalar or object

Error: Path does not point to array

Converts the node into the first element of a new array and appends the new value.

Path is NULL

Error. (MySQL silently returns NULL.)

Error. (MySQL silently returns NULL.)

Migrating from MySQL

  • NULL columns: MySQL returns NULL without updating. Lindorm SQL creates an empty array and performs the operation. Adjust any logic that depends on a NULL return.

  • NULL paths: MySQL returns NULL silently. Lindorm SQL throws an error. Validate the path before calling.

  • Other behaviors: Out-of-bounds appending, non-array node conversion, and sequential multi-parameter execution all match MySQL.