Skip to content

fix: make the Query/Scan refusal on a vector index reachable - #319

Merged
yesyayen merged 2 commits into
ExtendDB:mainfrom
yesyayen:fix/query-scan-vector-refusal
Aug 28, 2026
Merged

fix: make the Query/Scan refusal on a vector index reachable#319
yesyayen merged 2 commits into
ExtendDB:mainfrom
yesyayen:fix/query-scan-vector-refusal

Conversation

@yesyayen

@yesyayen yesyayen commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

What

Query and Scan naming an existing vector index returned the index-not-found message, indistinguishable from a nonexistent index. The intended refusals existed in both handlers but were dead code: a vector index is not a row in the indexes catalog, so index_info_by_table_id failed with IndexNotFound and the error propagated before the IndexType::Vector guard could run.

Both handlers now re-resolve an unresolved index name against the table's vector index metadata (engine-level, so every backend inherits it; backends without vector support are unchanged) and refuse with the messages and precedence captured from Amazon DynamoDB.

Behavior: today vs Amazon DynamoDB

All Amazon DynamoDB messages below were captured directly from the service (2026-08-20), on a table with an ACTIVE vector index vidx unless stated. Every case is 400 ValidationException except the two controls.

Scenario ExtendDB (before this PR) Amazon DynamoDB
Query with IndexName = vector index The table does not have the specified index: vidx Query operation not supported on this index type. (trailing period)
Scan with IndexName = vector index The table does not have the specified index: vidx Scan operation not supported on this index type (no period)
Query/Scan with a nonexistent IndexName The table does not have the specified index: nosuchindex same (unchanged contrast case)
Query on vector index + ConsistentRead: true index-not-found message Consistent reads are not supported on global secondary indexes (fires before the refusal, GSI wording even for a vector index)
Scan on vector index + ConsistentRead: true index-not-found message Scan operation not supported on this index type (refusal fires first)
Query on vector index, no KeyConditionExpression index-not-found message Either the KeyConditions or KeyConditionExpression parameter must be specified in the request. (fires before the refusal)
Query/Scan on vector index in CREATING, before backfill index-not-found message index-not-found message (same wording as a nonexistent index)
Query on vector index mid-backfill index-not-found message Query operation not supported on this index type.
Scan on vector index mid-backfill index-not-found message Cannot read from backfilling global secondary index: vidx
Query/Scan on the base table or a GSI of the same table 200 200 (controls, unchanged)

Why

Conformance gap found by comparing ExtendDB against Amazon DynamoDB. The wrong message actively misleads: it denies that an index exists when the request's actual problem is naming a vector index in an operation that can never serve it.

Closes # n/a

Testing done

Captured every expected message and ordering from Amazon DynamoDB first (including the lifecycle matrix, observed live through a backfill window), then validated dual-target. The branch was rebased onto current main after the vector-search backend PRs merged; all gates below were re-run at the rebased tip, not carried over.

  • New pytest tests/test_vector_index_query_scan.py (12 cases: both refusals whole-string, not-found contrast, four measured precedence orderings, base-table and GSI controls).
  • New wire tests in tests/rust: query_and_scan_on_a_vector_index_are_refused (refusals, contrast case, precedence, control) and scan_during_backfill_gets_the_backfilling_wording, which holds the backfill window open via the batch-delay setting, waits until CREATING with Backfilling: true is observed, and pins both mid-backfill messages in the same window.

Checklist

  • I have read CONTRIBUTING.md
  • All tests pass (cargo test --workspace)
  • Code is formatted (cargo fmt --check)
  • Clippy is clean (cargo clippy -- -W clippy::pedantic)
  • I have added or updated tests for new functionality
  • I have updated documentation if behavior changed
  • Breaking changes are noted below (if any)
  • If this changes the wire protocol, Storage trait, auth model, on-disk
    format, or public CLI surface, an RFC has been accepted or is linked
    below. Otherwise, an ADR captures the decision (link below).

ADR / RFC: n/a


By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache License 2.0 and I agree to the Developer Certificate of
Origin (DCO). See CONTRIBUTING.md for details.

A vector index is not a row in the indexes catalog, so
index_info_by_table_id reported it as missing and Query/Scan answered
"The table does not have the specified index" for an index the table
does have. The intended refusals were dead code.

On the index-not-found path both handlers now re-resolve the name
against the table's vector index metadata and refuse with the measured
messages: Query with "Query operation not supported on this index
type." (trailing period, measured 2026-08-20), Scan without one. A
backfilling index gets Scan's backfilling wording while Query keeps the
type refusal; an index CREATING before its backfill starts stays
index-not-found, all as measured. Measured precedence is preserved: on
Query the KeyConditionExpression and ConsistentRead checks fire before
the refusal, on Scan the refusal fires first.
Dual-target pytest and a wire test covering the refusals, the
index-not-found contrast case, the measured precedence against the
KeyConditionExpression and ConsistentRead checks, and base-table/GSI
controls.
@yesyayen
yesyayen marked this pull request as ready for review August 27, 2026 16:40

@LeeroyHannigan LeeroyHannigan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

@yesyayen
yesyayen added this pull request to the merge queue Aug 28, 2026
Merged via the queue into ExtendDB:main with commit 31906e4 Aug 28, 2026
22 checks passed
@yesyayen
yesyayen deleted the fix/query-scan-vector-refusal branch August 28, 2026 16:37
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