This is an automated email from the ASF dual-hosted git repository.

virajjasani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/phoenix-adapters.git


The following commit(s) were added to refs/heads/main by this push:
     new bec54ee  UpdateExpression tests for String literals with +/-
bec54ee is described below

commit bec54ee9729c6cf53c7c6b67f1b4d4c19182c165
Author: Palash Chauhan <[email protected]>
AuthorDate: Fri Jun 5 15:31:20 2026 -0700

    UpdateExpression tests for String literals with +/-
---
 .../apache/phoenix/ddb/UpdateItemBaseTests.java    | 69 ++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git 
a/phoenix-ddb-rest/src/test/java/org/apache/phoenix/ddb/UpdateItemBaseTests.java
 
b/phoenix-ddb-rest/src/test/java/org/apache/phoenix/ddb/UpdateItemBaseTests.java
index e758688..a131d28 100644
--- 
a/phoenix-ddb-rest/src/test/java/org/apache/phoenix/ddb/UpdateItemBaseTests.java
+++ 
b/phoenix-ddb-rest/src/test/java/org/apache/phoenix/ddb/UpdateItemBaseTests.java
@@ -210,6 +210,43 @@ public class UpdateItemBaseTests {
         validateItem(tableName, key);
     }
 
+    /**
+     * SET a literal string value that contains " - " and " + ". Such literals 
must be stored
+     * verbatim and must never be interpreted as arithmetic. Regression for a 
production UpdateItem
+     * failure where a JSON "properties" string contained " - " and Phoenix 
threw
+     * "Operand ... does not exist".
+     */
+    @Test(timeout = 120000)
+    public void testSetLiteralStringWithArithmeticOperators() {
+        final String tableName = 
testName.getMethodName().replaceAll("[\\[\\]]", "");
+        createTableAndPutItem(tableName, true);
+
+        Map<String, AttributeValue> key = getKey();
+        UpdateItemRequest.Builder uir = 
UpdateItemRequest.builder().tableName(tableName).key(key);
+        uir.updateExpression("SET #props = :props, #eq = :eq, #co = :co");
+        Map<String, String> exprAttrNames = new HashMap<>();
+        exprAttrNames.put("#props", "Properties");
+        exprAttrNames.put("#eq", "Equation");
+        exprAttrNames.put("#co", "Company");
+        uir.expressionAttributeNames(exprAttrNames);
+        Map<String, AttributeValue> exprAttrVal = new HashMap<>();
+        // Literal JSON string containing " - ".
+        exprAttrVal.put(":props", AttributeValue.builder()
+                .s("{\"teamName\":\"Foo - Bar Baz 
Service\",\"channelName\":\"#foo-notifications\"}")
+                .build());
+        // Literal string containing " + ".
+        exprAttrVal.put(":eq", AttributeValue.builder().s("E = mc^2 + 
offset").build());
+        // Plain literal that looks like a subtraction of two field names.
+        exprAttrVal.put(":co", AttributeValue.builder().s("Acme - 
Widgets").build());
+        uir.expressionAttributeValues(exprAttrVal);
+        uir.returnValues(ALL_NEW);
+        UpdateItemResponse dynamoResult = 
dynamoDbClient.updateItem(uir.build());
+        UpdateItemResponse phoenixResult = 
phoenixDBClientV2.updateItem(uir.build());
+        Assert.assertEquals(dynamoResult.attributes(), 
phoenixResult.attributes());
+
+        validateItem(tableName, key);
+    }
+
     /**
      * SET: list_append against an existing list attribute path, plus a 
parallel
      * "create-or-append" using if_not_exists for a previously-missing list, 
plus a
@@ -986,6 +1023,38 @@ public class UpdateItemBaseTests {
         validateItem(tableName, key);
     }
 
+    /**
+     * Legacy AttributeUpdates PUT of literal string values that contain " - " 
and " + ". Same
+     * regression as {@link #testSetLiteralStringWithArithmeticOperators()}, 
exercised through the
+     * legacy AttributeUpdates parameter path. Literals must be stored 
verbatim and never parsed as
+     * arithmetic.
+     */
+    @Test(timeout = 120000)
+    public void testAttributeUpdatesLiteralStringWithArithmeticOperators() {
+        final String tableName = 
testName.getMethodName().replaceAll("[\\[\\]]", "");
+        createTableAndPutItem(tableName, true);
+
+        Map<String, AttributeValue> key = getKey();
+
+        Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<>();
+        // PUT a literal JSON string containing " - ".
+        attributeUpdates.put("Properties", 
AttributeValueUpdate.builder().action(AttributeAction.PUT)
+                .value(AttributeValue.builder()
+                        .s("{\"teamName\":\"Foo - Bar Baz 
Service\",\"channelName\":\"#foo-notifications\"}")
+                        .build()).build());
+        // PUT a literal string containing " + ".
+        attributeUpdates.put("Language", 
AttributeValueUpdate.builder().action(AttributeAction.PUT)
+                .value(AttributeValue.builder().s("C++ - systems 
programming").build()).build());
+
+        UpdateItemRequest updateRequest = 
UpdateItemRequest.builder().tableName(tableName).key(key)
+                .attributeUpdates(attributeUpdates).build();
+
+        dynamoDbClient.updateItem(updateRequest);
+        phoenixDBClientV2.updateItem(updateRequest);
+
+        validateItem(tableName, key);
+    }
+
     /**
      * Test AttributeUpdates validation - should reject when both 
UpdateExpression and AttributeUpdates are provided.
      */

Reply via email to