-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Open
Labels
status: triage neededRequires evaluation by maintainersRequires evaluation by maintainerstype: bugBug reportBug report
Description
Is there an existing issue for this?
- I have searched the existing issues
Current Behavior
The RDS Data API (rds-data execute-statement
) consistently returns numberOfRecordsUpdated: 0
for all DML operations (INSERT, UPDATE, DELETE), even when these operations successfully modify data in the database.
From the test output:
- CREATE TABLE: Returns
numberOfRecordsUpdated: 0
(expected, as DDL operations don't update records) - INSERT: Returns
numberOfRecordsUpdated: 0
(should return 1) - SELECT: Returns
numberOfRecordsUpdated: 0
and shows the data was inserted correctly - UPDATE: Returns
numberOfRecordsUpdated: 0
(should return 1) - DELETE: Returns
numberOfRecordsUpdated: 0
(should return 1)
The operations themselves work correctly (data is inserted, updated, deleted), but the API response field numberOfRecordsUpdated
is always 0.
Expected Behavior
According to the AWS RDS Data API documentation, the numberOfRecordsUpdated
field should contain:
The number of records updated by the request.
Expected behavior:
- INSERT INTO table VALUES (...):
numberOfRecordsUpdated: 1
- UPDATE table SET ... WHERE id = 1:
numberOfRecordsUpdated: 1
- DELETE FROM table WHERE id = 1:
numberOfRecordsUpdated: 1
- SELECT:
numberOfRecordsUpdated: 0
(correct, as SELECT doesn't modify data)
How are you starting LocalStack?
With the localstack
script
Steps To Reproduce
How are you starting localstack
SERVICES=rds,rds-data,secretsmanager localstack start
Client commands
# Set up environment
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1
DATABASE_NAME="testdb"
# Create secret for database credentials
SECRET_CREATE_OUTPUT=$(awslocal secretsmanager create-secret \
--name test-secret \
--secret-string '{"username":"testuser","password":"testpass"}' \
--region us-east-1)
SECRET_ARN=$(echo "$SECRET_CREATE_OUTPUT" | jq -r '.ARN')
# Create Aurora cluster
CLUSTER_CREATE_OUTPUT=$(awslocal rds create-db-cluster \
--db-cluster-identifier test-cluster \
--engine aurora-postgresql \
--master-username testuser \
--master-user-password testpass \
--database-name "$DATABASE_NAME" \
--region us-east-1)
CLUSTER_ARN=$(echo "$CLUSTER_CREATE_OUTPUT" | jq -r '.DBCluster.DBClusterArn')
# 1. CREATE TABLE (returns numberOfRecordsUpdated: 0 - correct)
awslocal rds-data execute-statement \
--resource-arn "$CLUSTER_ARN" \
--secret-arn "$SECRET_ARN" \
--database "$DATABASE_NAME" \
--sql "CREATE TABLE test_table (id SERIAL PRIMARY KEY, name VARCHAR(50));"
# 2. INSERT (BUG: returns numberOfRecordsUpdated: 0, should be 1)
awslocal rds-data execute-statement \
--resource-arn "$CLUSTER_ARN" \
--secret-arn "$SECRET_ARN" \
--database "$DATABASE_NAME" \
--sql "INSERT INTO test_table (name) VALUES ('initial_name');" \
--output json
# 3. Verify INSERT worked - SELECT shows data exists
SELECT_RESULT=$(awslocal rds-data execute-statement \
--resource-arn "$CLUSTER_ARN" \
--secret-arn "$SECRET_ARN" \
--database "$DATABASE_NAME" \
--sql "SELECT id, name FROM test_table;" \
--output json)
RECORD_ID=$(echo "$SELECT_RESULT" | jq -r '.records[0][0].longValue')
# 4. UPDATE (BUG: returns numberOfRecordsUpdated: 0, should be 1)
awslocal rds-data execute-statement \
--resource-arn "$CLUSTER_ARN" \
--secret-arn "$SECRET_ARN" \
--database "$DATABASE_NAME" \
--sql "UPDATE test_table SET name = 'updated_name' WHERE id = $RECORD_ID;" \
--output json
# 5. DELETE (BUG: returns numberOfRecordsUpdated: 0, should be 1)
awslocal rds-data execute-statement \
--resource-arn "$CLUSTER_ARN" \
--secret-arn "$SECRET_ARN" \
--database "$DATABASE_NAME" \
--sql "DELETE FROM test_table WHERE id = $RECORD_ID;" \
--output json
Actual Output
# CREATE TABLE response (correct)
{"numberOfRecordsUpdated": 0, "generatedFields": []}
# INSERT response (BUG: should be 1)
{"numberOfRecordsUpdated": 0, "generatedFields": []}
# SELECT response (shows INSERT worked)
{
"records": [[{"longValue": 1}, {"stringValue": "initial_name"}]],
"numberOfRecordsUpdated": 0
}
# UPDATE response (BUG: should be 1)
{"numberOfRecordsUpdated": 0, "generatedFields": []}
# DELETE response (BUG: should be 1)
{"numberOfRecordsUpdated": 0, "generatedFields": []}
Environment
- OS: Linux (Debian GNU/Linux 12 bookworm in dev container)
- LocalStack:
- LocalStack version: 4.7.1.dev29
- LocalStack build date: 2025-08-08
- LocalStack build git hash: 2521cefc7
Anything else?
This bug breaks compatibility with SQLAlchemy and other ORMs that rely on numberOfRecordsUpdated
for:
- Optimistic concurrency control
- Detecting successful operations
- Batch operation result validation
Metadata
Metadata
Assignees
Labels
status: triage neededRequires evaluation by maintainersRequires evaluation by maintainerstype: bugBug reportBug report