fix: CREATE UNIQUE INDEX actually enforces uniqueness (and persists)
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled

This commit is contained in:
2026-07-30 17:13:29 +03:00
parent 5858a9da17
commit e8f9cbc5bb
8 changed files with 122 additions and 8 deletions
+36
View File
@@ -321,3 +321,39 @@ suite "Bug fixes — clause keywords usable as identifiers":
let a4 = parse("EXPORT TO 'o.csv' FROM t FORMAT csv DELIMITER ';' HEADER false")
check a4.stmts[0].expFormat == "csv"
check a4.stmts[0].expIncludeHeader == false
suite "Bug fixes — UNIQUE index enforcement":
test "CREATE UNIQUE INDEX rejects duplicate INSERT":
var ctx = setupCtx()
defer: teardown(ctx)
discard executeQuery(ctx, parse("CREATE TABLE accts (id INTEGER PRIMARY KEY, email TEXT)"))
discard executeQuery(ctx, parse("INSERT INTO accts (id, email) VALUES (1, 'a@b.c')"))
let c = executeQuery(ctx, parse("CREATE UNIQUE INDEX accts_email ON accts (email)"))
check c.success
let dup = executeQuery(ctx, parse("INSERT INTO accts (id, email) VALUES (2, 'a@b.c')"))
check not dup.success
let ok = executeQuery(ctx, parse("INSERT INTO accts (id, email) VALUES (2, 'x@y.z')"))
check ok.success
test "CREATE UNIQUE INDEX rejects duplicate UPDATE":
var ctx = setupCtx()
defer: teardown(ctx)
discard executeQuery(ctx, parse("CREATE TABLE accts (id INTEGER PRIMARY KEY, email TEXT)"))
discard executeQuery(ctx, parse("INSERT INTO accts (id, email) VALUES (1, 'a@b.c')"))
discard executeQuery(ctx, parse("INSERT INTO accts (id, email) VALUES (2, 'x@y.z')"))
let c = executeQuery(ctx, parse("CREATE UNIQUE INDEX accts_email ON accts (email)"))
check c.success
let dup = executeQuery(ctx, parse("UPDATE accts SET email = 'a@b.c' WHERE id = 2"))
check not dup.success
let same = executeQuery(ctx, parse("UPDATE accts SET email = 'a@b.c' WHERE id = 1"))
check same.success
test "CREATE UNIQUE INDEX over duplicate data fails":
var ctx = setupCtx()
defer: teardown(ctx)
discard executeQuery(ctx, parse("CREATE TABLE accts (id INTEGER PRIMARY KEY, email TEXT)"))
discard executeQuery(ctx, parse("INSERT INTO accts (id, email) VALUES (1, 'a@b.c')"))
discard executeQuery(ctx, parse("INSERT INTO accts (id, email) VALUES (2, 'a@b.c')"))
let c = executeQuery(ctx, parse("CREATE UNIQUE INDEX accts_email ON accts (email)"))
check not c.success
+24
View File
@@ -441,6 +441,30 @@ suite "Schema persistence":
db2.close()
removeDir(dir)
test "UNIQUE B-tree index survives reopen and still enforces":
let dir = "/tmp/baradb_schema_persist_unique"
removeDir(dir)
block:
var db = newLSMTree(dir)
var ctx = newExecutionContext(db)
check execSql(ctx, "CREATE TABLE accts (id INTEGER PRIMARY KEY, email TEXT)").success
check execSql(ctx, "CREATE UNIQUE INDEX accts_email ON accts (email)").success
check execSql(ctx, "INSERT INTO accts (id, email) VALUES (1, 'a@b.c')").success
check "accts.email" in ctx.btrees
db.close()
# Reopen fresh context (simulates process restart)
block:
var db2 = newLSMTree(dir)
var ctx2 = newExecutionContext(db2)
# UNIQUE flag must survive restart via the persisted DDL.
check "accts.email" in ctx2.btrees
let dup = execSql(ctx2, "INSERT INTO accts (id, email) VALUES (2, 'a@b.c')")
check not dup.success
let ok = execSql(ctx2, "INSERT INTO accts (id, email) VALUES (2, 'x@y.z')")
check ok.success
db2.close()
removeDir(dir)
test "Stable schema key format":
check tableSchemaKey("users") == "_schema:tables:users"
check serializeTableDdl(TableDef(