Skip to content

Support for multi-index uniqueness constraints #153

@joamaki

Description

@joamaki

Consider the following:

type Object struct {
  A string
  B string
}

var (
  AIndex = index[...]{
    FromObject: ... return index.NewKeySet(index.String(obj.A)) ...
    Unique: true,
  }
  BIndex = index[...]{
    FromObject: ... return index.NewKeySet(index.String(obj.B)) ...
    Unique: true,
  }
}

func NewObjectTable(db *DB) (RWTable[Object], error) {
  return NewTable(db, "objects", AIndex, BIndex)
}

var tbl RWTable[Object]
wtxn := db.WriteTxn(tbl)
tbl.Insert(wtxn, Object{"A", "B"})
tbl.Insert(wtxn, Object{"B", "B"})
wtxn.Commit()

Following the inserts the indexes now contain:

AIndex = {"A": Object{"A", "B"}, "B": Object{"B", "B"}}
BIndex = {"B": Object{"B", "B"}}

We've now silently lost the association from "B" to Object{"A", "B"}. For most use-cases this is a bug and the fact that this overriding happens silently could be a foot-gun. The one use-case where I could see this behavior being useful is to have a "latest" index.

Consider adding support for validating that an entry in a secondary unique index can only be replaced if the primary keys match.
Since Insert errors are not often checked currently (they're currently exceptional errors such as trying to insert with a WriteTxn that doesn't lock the table), also consider adding support for configuring the handling for errors to allow panicing in CI tests and logging errors in production.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions