agentm / project-m36

Project: M36 Relational Algebra Engine
The Unlicense
876 stars 47 forks source link

Inconsistent DB state after `undefine` #306

Closed farzadbekran closed 2 years ago

farzadbekran commented 2 years ago

When I define two RelVars, add a foreign key, insert a couple of tuples and undefine the RelVar being referenced by the other one, no errors occur, which leads to an inconsistency in the DB.

To reproduce, do these in tutd:

TutorialD (master/main): x := relation{ax Integer, bx Text}
TutorialD (master/main): y := relation{ay Integer, by Text}
TutorialD (master/main): foreign key fk_ay_in_ax y{ay} in x{ax} rename {ax as ay}
TutorialD (master/main): insert x relation{tuple{ax 1, bx "test"}}
TutorialD (master/main): insert y relation{tuple{ay 1, by "test"}}
TutorialD (master/main): :commit
TutorialD (master/main): :constraints
┌─────────────┬─────────┬─────────────────────────────┐
│name::Text   │sub::Text│super::Text                  │
├─────────────┼─────────┼─────────────────────────────┤
│"fk_ay_in_ax"│"(y{ay})"│"((x{ax} rename {ax as ay}))"│
└─────────────┴─────────┴─────────────────────────────┘
TutorialD (master/main): undefine x
TutorialD (master/main): :commit
TutorialD (master/main): insert y relation{tuple{ay 2, by "test2"}}
ERR: RelVarNotDefinedError "x"
TutorialD (master/main): :showexpr y
┌───────────┬────────┐
│ay::Integer│by::Text│
├───────────┼────────┤
│1          │"test"  │
└───────────┴────────┘

I think undefining x should not be allowed here, since it breaks foreign key constraint for y.

agentm commented 2 years ago

Woah, a serious issue indeed! Thanks for the detailed write-up.

agentm commented 2 years ago

Here's a simpler means of reproducing the issue:

x:=true
constraint x equals true
undefine x
:commit
y:=false
ERR: RelVarNotDefinedError "x"

This is caused by the lack of constraint checking in relation undefinition. Oops!