mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-27 04:54:21 +01:00
Closes #1384 . This PR implements Primary Key constraint for inserts. As can be seen in the issue, if you created an Index with a Primary Key constraint, it could trigger `Unique Constraint` error, but still insert the record. Sqlite uses the opcode `NoConflict` to check if the record already exists in the Btree. As we did not have this Opcode yet, I implemented it. It is very similar to `NotFound` with the difference that if any value in the Record is Null, it will immediately jump to the offset. The added benefit of implementing this, is that now we fully support Composite Primary Keys. Also, I think with the current implementation, it will be trivial to implement the Unique opcode for Insert. To support Updates, I need to understand more of the plan optimizer to and find where we are Making the Record and opening the autoindex. For testing, I have written a test generator to generate many different tables that can have a varying numbers of Primary Keys. ```sql limbo> CREATE TABLE users (id INT, username TEXT, PRIMARY KEY (id, username)); limbo> INSERT INTO users VALUES (1, 'alice'); limbo> explain INSERT INTO users VALUES (1, 'alice'); addr opcode p1 p2 p3 p4 p5 comment ---- ----------------- ---- ---- ---- ------------- -- ------- 0 Init 0 16 0 0 Start at 16 1 OpenWrite 0 2 0 0 2 Integer 1 2 0 0 r[2]=1 3 String8 0 3 0 alice 0 r[3]='alice' 4 OpenWrite 1 3 0 0 5 NewRowId 0 1 0 0 6 Copy 2 5 0 0 r[5]=r[2] 7 Copy 3 6 0 0 r[6]=r[3] 8 Copy 1 7 0 0 r[7]=r[1] 9 MakeRecord 5 3 8 0 r[8]=mkrec(r[5..7]) 10 NoConflict 1 12 5 2 0 key=r[5] 11 Halt 1555 0 0 users.id, users.username 0 12 IdxInsert 1 8 5 0 key=r[8] 13 MakeRecord 2 2 4 0 r[4]=mkrec(r[2..3]) 14 Insert 0 4 1 0 15 Halt 0 0 0 0 16 Transaction 0 1 0 0 write=true 17 Goto 0 1 0 0 limbo> INSERT INTO users VALUES (1, 'alice'); × Runtime error: UNIQUE constraint failed: users.id, users.username (19) limbo> INSERT INTO users VALUES (1, 'bob'); limbo> INSERT INTO users VALUES (1, 'bob'); × Runtime error: UNIQUE constraint failed: users.id, users.username (19) ``` Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com> Closes #1393