{"record":{"id":"6a87e9659905c063","repo":"hibernate/hibernate-orm","slug":"singlestore-json-array-insert-function-last-path-p","errorCode":null,"errorMessage":"SingleStore json_array_insert function last path parameter must be an array index element","messagePattern":"SingleStore json_array_insert function last path parameter must be an array index element","errorType":"exception","errorClass":"QueryException","httpStatus":null,"severity":"error","filePath":"hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/function/json/SingleStoreJsonArrayInsertFunction.java","lineNumber":80,"sourceCode":"\t\tjson.accept( translator );\n\t\tbuildJsonPath( sqlAppender, jsonPath, jsonPathElements );\n\t\tsqlAppender.appendSql( \")),\" );\n\t\tsqlAppender.appendSql( arrayIndex );\n\t\tsqlAppender.appendSql( \", 0, \" );\n\t\tvalue.accept( translator );\n\t\tsqlAppender.appendSql( \") END\" );\n\t\tif ( jsonPathElements.size() > 1 ) {\n\t\t\tsqlAppender.appendSql( ')' );\n\t\t}\n\t}\n\n\tprivate static int getArrayIndex(List<JsonPathHelper.JsonPathElement> jsonPathElements) {\n\t\tif ( jsonPathElements.isEmpty() ) {\n\t\t\tthrow new QueryException( \"SingleStore json_array_insert function requires at least one json path element\" );\n\t\t}\n\t\tJsonPathHelper.JsonPathElement lastPathElement = jsonPathElements.get( jsonPathElements.size() - 1 );\n\t\tif ( !( lastPathElement instanceof JsonPathHelper.JsonIndexAccess ) ) {\n\t\t\tthrow new QueryException(\n\t\t\t\t\t\"SingleStore json_array_insert function last path parameter must be an array index element\" );\n\t\t}\n\t\treturn ( (JsonPathHelper.JsonIndexAccess) lastPathElement ).index();\n\t}\n\n\tprivate static boolean isNumeric(SqlAstNode value) {\n\t\treturn value instanceof UnparsedNumericLiteral<?>;\n\t}\n\n\tprivate static void buildJsonArrayInsertValue(SqlAppender sqlAppender, SqlAstNode value) {\n\t\tsqlAppender.appendSql( \"json_splice_\" );\n\t\tsqlAppender.appendSql( isNumeric( value ) ? \"double(\" : \"string(\" );\n\t}\n\n\tprivate static void buildJsonPath(\n\t\t\tSqlAppender sqlAppender, Expression jsonPath, List<JsonPathHelper.JsonPathElement> jsonPathElements) {\n\t\tfor ( int i = 0; i < jsonPathElements.size() - 1; i++ ) {\n\t\t\tJsonPathHelper.JsonPathElement pathElement = jsonPathElements.get( i );","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/function/json/SingleStoreJsonArrayInsertFunction.java#L62-L98","documentation":"The SingleStore json_array_insert emulation derives the splice position from the LAST path element, which must be an array index access like [1]. If the final element is an attribute or the path is otherwise not index-terminated, getArrayIndex cannot determine where to insert and throws QueryException.","triggerScenarios":"HQL `json_array_insert(e.doc, 'items[0].label', :v)` — any path whose last segment is not [n] — on SingleStoreDialect.","commonSituations":"Paths written object-insert style (json_set/json_insert semantics) reused with json_array_insert; path-building code that drops the trailing index by an off-by-one.","solutions":["End the path with the target array index: 'items[0]'","Use json_set/json_insert (or json_object building) when the target is an object attribute","Assert in code that generated paths end with [<int>] before running the query"],"exampleFix":"// before (last segment is an attribute)\nupdate E e set e.doc = json_array_insert(e.doc, 'items[0].label', :v)\n\n// after (last segment is an array index)\nupdate E e set e.doc = json_array_insert(e.doc, 'items[0]', :v)","handlingStrategy":"validation","validationCode":"// Last path segment must be an array index [n]\nprivate static final Pattern ENDS_WITH_INDEX = Pattern.compile(\"\\\\[\\\\d+\\\\]\\\\s*$\");\nstatic boolean validInsertPath(String path) {\n    return path != null && !\"$\".equals(path.trim()) && ENDS_WITH_INDEX.matcher(path).find();\n}","typeGuard":null,"tryCatchPattern":"try {\n    em.createQuery(hql).executeUpdate();\n} catch (QueryException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"array index element\")) {\n        // fix the path to end with [n] or switch to json_set for object targets\n    }\n    throw e;\n}","preventionTips":["Assert generated json_array_insert paths end with a numeric index","Use json_set/json_insert for object attributes; json_array_insert only for array positions","Log the offending path in tests to catch off-by-one path builders"],"tags":["hibernate","singlestore","json-array-insert","json-path"],"backgroundTag":"json-array-insert-path-invalid","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}