createVectorIndex method

void createVectorIndex(
  1. VectorIndexSpec spec
)

Register a vector index on spec.table.spec.column. The index is built the first time a query uses it and automatically rebuilt after any mutation of the target table.

Throws StateError if the target table or column doesn't exist, or if an index is already registered on that column.

Implementation

void createVectorIndex(VectorIndexSpec spec) {
  final key = '${spec.table.toLowerCase()}:${spec.column.toLowerCase()}';
  if (_vectorIndexes.containsKey(key)) {
    throw StateError(
      'vector index already registered on ${spec.table}.${spec.column}',
    );
  }
  // Paged tables use PK-keyed rowids and must be warmed via
  // `warmVectorIndexes()` before queries can use the index — the
  // planner's sync fast path can't drive an async `pt.scan()`.
  final pt = _pagedTable(spec.table);
  if (pt != null) {
    final col = pt.columns.firstWhere(
      (c) => c.name.toLowerCase() == spec.column.toLowerCase(),
      orElse: () => throw StateError(
        'createVectorIndex: no such column: ${spec.table}.${spec.column}',
      ),
    );
    // Just check the column exists; register the binding.
    // ignore: unused_local_variable
    final _ = col;
    _vectorIndexes[key] = _VectorIndexBinding(spec);
    return;
  }
  final t = _tables[spec.table];
  if (t == null) {
    throw StateError('createVectorIndex: no such table: ${spec.table}');
  }
  final colIdx = t.columns.indexWhere(
    (c) => c.name.toLowerCase() == spec.column.toLowerCase(),
  );
  if (colIdx < 0) {
    throw StateError(
      'createVectorIndex: no such column: ${spec.table}.${spec.column}',
    );
  }
  _vectorIndexes[key] = _VectorIndexBinding(spec);
}