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
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:
@@ -4,6 +4,7 @@
|
||||
## Also hosts the AST-to-SQL serializer used for VIEW DDL persistence.
|
||||
import std/strutils
|
||||
import std/tables
|
||||
import std/sets
|
||||
import std/locks
|
||||
import ../ast
|
||||
import ../../storage/lsm
|
||||
@@ -28,6 +29,7 @@ var restoreEnginesHook*: proc(ctx: ExecutionContext)
|
||||
proc newExecutionContext*(db: LSMTree, registry: DatabaseRegistry = nil): ExecutionContext =
|
||||
result = ExecutionContext(db: db, tables: initTable[string, TableDef](),
|
||||
btrees: initTable[string, BTreeIndex[string, IndexEntry]](),
|
||||
uniqueIndexes: initHashSet[string](),
|
||||
views: initTable[string, Node](),
|
||||
cteTables: initTable[string, seq[Row]](),
|
||||
ftsIndexes: initTable[string, fts.InvertedIndex](),
|
||||
@@ -161,6 +163,7 @@ proc cloneForConnection*(ctx: ExecutionContext): ExecutionContext =
|
||||
svCopy[k] = v
|
||||
result = ExecutionContext(db: ctx.db, tables: ctx.tables,
|
||||
btrees: ctx.btrees, views: ctx.views,
|
||||
uniqueIndexes: ctx.uniqueIndexes,
|
||||
cteTables: initTable[string, seq[Row]](),
|
||||
ftsIndexes: ctx.ftsIndexes,
|
||||
vectorIndexes: ctx.vectorIndexes,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
## Extracted from `executor.nim` (Task 9 of the executor split).
|
||||
import std/strutils
|
||||
import std/tables
|
||||
import std/sets
|
||||
import std/sequtils
|
||||
import ../../storage/lsm
|
||||
import ../../storage/btree
|
||||
@@ -21,6 +22,28 @@ import rls
|
||||
# Table storage
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
proc violatesUniqueIndex*(ctx: ExecutionContext, table: string, fields: seq[string],
|
||||
rowVals: seq[string], excludeLsmKey: string = ""): string =
|
||||
## Returns the colKey of the first standalone UNIQUE index this row
|
||||
## violates, or "" when the row is clean. idxVal is built with the exact
|
||||
## convention of the CREATE INDEX population loop (getValue yields "\\N"
|
||||
## for a missing column, values joined with "|"). excludeLsmKey lets UPDATE
|
||||
## ignore the row's own existing entry.
|
||||
if ctx.uniqueIndexes.len == 0: return ""
|
||||
for colKey in ctx.uniqueIndexes:
|
||||
if not colKey.startsWith(table & "."): continue
|
||||
let idxCols = colKey[table.len + 1..^1].split(".")
|
||||
var colVals: seq[string] = @[]
|
||||
for c in idxCols:
|
||||
colVals.add(getValue(rowVals, fields, c))
|
||||
let idxVal = colVals.join("|")
|
||||
if idxVal.len == 0 or isNull(idxVal): continue
|
||||
if colKey notin ctx.btrees: continue
|
||||
for entry in ctx.btrees[colKey].get(idxVal):
|
||||
if entry.lsmKey != excludeLsmKey:
|
||||
return colKey
|
||||
return ""
|
||||
|
||||
proc execInsert*(ctx: ExecutionContext, table: string, fields: seq[string], values: seq[seq[string]],
|
||||
kvPairs: var seq[(string, seq[byte])]): int =
|
||||
if not hasPrivilege(ctx, table, "INSERT"):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
## Executor types — shared by all exec/* modules and executor.nim
|
||||
import std/tables
|
||||
import std/sets
|
||||
import std/locks
|
||||
import ../ast
|
||||
import ../ir
|
||||
@@ -92,6 +93,7 @@ type
|
||||
db*: LSMTree
|
||||
tables*: Table[string, TableDef]
|
||||
btrees*: Table[string, BTreeIndex[string, IndexEntry]]
|
||||
uniqueIndexes*: HashSet[string] # colKeys (table.col[.col...]) of UNIQUE standalone B-tree indexes
|
||||
views*: Table[string, Node] # view name -> SELECT AST
|
||||
cteTables*: Table[string, seq[Row]] # CTE name -> rows
|
||||
ftsIndexes*: Table[string, fts.InvertedIndex] # table.col -> FTS index
|
||||
|
||||
Reference in New Issue
Block a user