Skip to content

fix: not-equals on missing attribute returns false instead of true#8

Merged
hicksy merged 2 commits into
nubo-db:mainfrom
AnatolyRugalev:fix/ne-missing-attribute
Apr 24, 2026
Merged

fix: not-equals on missing attribute returns false instead of true#8
hicksy merged 2 commits into
nubo-db:mainfrom
AnatolyRugalev:fix/ne-missing-attribute

Conversation

@AnatolyRugalev

Copy link
Copy Markdown
Contributor

Summary

The <> (not-equals) comparison operator returns false when either operand is a missing attribute. DynamoDB returns true — a non-existent value is not equal to any value.

Version: dynoxide 0.9.8

Reproduction

dynoxide --port 8000 &

export AWS_ACCESS_KEY_ID=fake AWS_SECRET_ACCESS_KEY=fake \
       AWS_DEFAULT_REGION=us-east-1 EP=http://localhost:8000

aws dynamodb create-table --endpoint-url $EP \
  --table-name test --billing-mode PAY_PER_REQUEST \
  --attribute-definitions AttributeName=pk,AttributeType=S \
  --key-schema AttributeName=pk,KeyType=HASH

# PutItem with condition: status <> "working" on a non-existent item
# Should succeed — missing attribute is not equal to "working"
aws dynamodb put-item --endpoint-url $EP --table-name test \
  --item '{"pk":{"S":"item1"},"status":{"S":"idle"}}' \
  --condition-expression '#s <> :v' \
  --expression-attribute-names '{"#s":"status"}' \
  --expression-attribute-values '{":v":{"S":"working"}}'
# => ConditionalCheckFailedException (should succeed)

Expected

PutItem succeeds. status <> "working" is true because the item has no status attribute.

Root cause

In condition.rs, the Comparison evaluator returns false for all operators when either operand resolves to None:

match (lv, rv) {
    (Some(l), Some(r)) => Ok(compare_values(&l, op, &r)),
    _ => Ok(false),  // ← should be true for Ne
}

Fix

Return true for <> when either operand is missing, false for all other operators:

_ => Ok(matches!(op, CompOp::Ne)),

Regression tests cover all six comparison operators on missing attributes. Also submitted as a conformance test: nubo-db/dynamodb-conformance#1

@hicksy hicksy force-pushed the fix/ne-missing-attribute branch from be5513d to aefcbc2 Compare April 24, 2026 17:11
AnatolyRugalev and others added 2 commits April 24, 2026 18:56
… of true

When either operand of a comparison is missing (attribute doesn't exist),
all operators returned false — including <> (not-equals). DynamoDB
returns true for <> on missing attributes: a non-existent value is not
equal to anything.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hicksy hicksy force-pushed the fix/ne-missing-attribute branch from aefcbc2 to 69c2670 Compare April 24, 2026 17:56
@hicksy

hicksy commented Apr 24, 2026

Copy link
Copy Markdown
Member

Two small edits pushed to your branch:

  1. Rebased onto current main as our workflows have been updated there recently.
  2. cargo fmt (minor formatting fixes). No logic change.

As you were a first time contributor the CI checks needed approval. CI is approved and running; I'm leaving benchmark-regression unapproved for now (unrelated housekeeping). Will merge once CI is green.

@hicksy hicksy merged commit 0c83652 into nubo-db:main Apr 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants