Skip to content

CREATE VECTOR INDEX ignores unrecognized option tokens and accepts DIM 0, creating an index that never matches #213

Description

@mkhairi

Version / build tested against

origin/main @ 7bd4d24

Deployment mode

Origin — single node (local)

Engine(s) involved

Vector

Summary

CREATE VECTOR INDEX scans its tail for known option keywords and ignores everything it does not recognize, and it accepts the resulting DIM 0. Any spelling that does not use the bare DIM <n> keyword — for example the Postgres/pgvector-shaped WITH (dim = 3, metric = 'cosine') — is reported as a successful CREATE VECTOR INDEX but builds an index with dimension 0, and every subsequent SEARCH ... USING VECTOR(...) on that collection returns 0 rows with no error. The user sees valid DDL, valid inserts, and an empty result set with nothing to diagnose from.

Steps to reproduce

-- unrecognized option syntax: accepted, index is inert
DROP COLLECTION IF EXISTS vec_bad;
CREATE COLLECTION vec_bad;
CREATE VECTOR INDEX idx_vec_bad ON vec_bad (embedding) WITH (dim = 3, metric = 'cosine');
-- CREATE VECTOR INDEX        <- no error, no warning
INSERT INTO vec_bad (id, title, embedding) VALUES
  ('a1','one',ARRAY[0.1,0.2,0.3]), ('a2','two',ARRAY[0.4,0.5,0.6]);
SELECT id, title FROM vec_bad;
--  a1 | one
--  a2 | two               (2 rows)   <- rows are there
SEARCH vec_bad USING VECTOR(embedding, ARRAY[0.1,0.2,0.3], 2);
-- (0 rows)                           <- WRONG, silent

-- documented keyword syntax, identical data: works
DROP COLLECTION IF EXISTS vec_good;
CREATE COLLECTION vec_good;
CREATE VECTOR INDEX idx_vec_good ON vec_good (embedding) METRIC COSINE DIM 3;
INSERT INTO vec_good (id, title, embedding) VALUES
  ('a1','one',ARRAY[0.1,0.2,0.3]), ('a2','two',ARRAY[0.4,0.5,0.6]);
SEARCH vec_good USING VECTOR(embedding, ARRAY[0.1,0.2,0.3], 2);
--  id | _surrogate |      distance
--  a1 | 210        | 0.0
--  a2 | 211        | 0.27000001072883606      (2 rows)

The same silent-empty outcome occurs for a collection created with USING vector and no CREATE VECTOR INDEX at all.

Expected behavior

Either the option tokens are parsed, or the statement is rejected. Specifically: unrecognized trailing tokens should raise a syntax error rather than being skipped, and DIM 0 (explicit or defaulted) should be rejected at DDL time — an index that can never match anything should not be creatable.

Actual behavior

CREATE VECTOR INDEX returns success. The keyword scan finds no DIM token, falls back to dim = 0 (find_param_usize(&upper_parts, "DIM").unwrap_or(0) in the DDL handler), and validate_quantization does not reject a zero dimension for the default hnsw index type. The index is registered, inserts succeed, and searches return an empty result set indistinguishable from "no neighbours found".

What actually happened? (check all that are true)

  • Acknowledged/committed data was lost, corrupted, or silently wrong
  • The server crashed, hung, or failed to start
  • A security or isolation boundary was crossed
  • Core functionality is broken with no acceptable workaround
  • A workaround exists (rewrite the query, avoid one path, etc.)

Proposed severity

SEV-2 — High: major functionality broken or silently-wrong results; stored data intact

Reproducibility

Always — every attempt

Last known-good version / commit (if a regression)

(blank — not a regression as far as tested)

Environment & logs

Linux x86_64, release build from source (nodedb 0.4.0, git commit: 7bd4d24b6). Single local node, fresh data directory. No server-side log line accompanies the inert index creation.

Files (best guess): nodedb/src/control/server/shared/ddl/neutral/dsl/vector_index.rs — the handler uppercases the tail and picks known keywords out of it (METRIC, M, EF_CONSTRUCTION, DIM, INDEX_TYPE, PQ_M, IVF_CELLS, IVF_NPROBE), with no rejection of leftover tokens and DIM defaulting to 0.

Before submitting

  • I searched existing issues and this is not a duplicate.
  • I reproduced this on a released tag or a current main build (not a stale local branch).
  • This is not a security vulnerability (those go to a private advisory).

Metadata

Metadata

Assignees

Labels

area:sqlParser, planner, SQL semanticsengine:vectorVector enginepriority:P1Fix in the current milestonesev:2-highMajor functionality broken; no acceptable workaroundtype:bugA defect — broken, incorrect, or lost data

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions