AmpersandTarski / Ampersand

Build database applications faster than anyone else, and keep your data pollution free as a bonus.
http://ampersandtarski.github.io/
GNU General Public License v3.0
40 stars 8 forks source link

Insert into a univalent relation should give the correct error message. #1420

Open stefjoosten opened 1 year ago

stefjoosten commented 1 year ago

What happened

When experimenting with enforcement rules, I tried the following script:

CONTEXT Issue1420

RELATION r[S*T]
RELATION s[S*T] [UNI]
POPULATION r[S*T] CONTAINS
  [ ("aap","noot"), ("aap","mies") ]

ENFORCE s >: r

ENDCONTEXT

What I expected

I expected this script to fail upon startup because relation s is univalent. So, trying to copy the contents of r into s should fail with a violation of univalence.

What I got

Instead, I got a maximum number of reruns violation: afbeelding

Version of Ampersand that was used

I used rap.tarski.nl running Ampersand-v4.6.2 to try this out

Steps to reproduce

  1. Log in into rap.tarski.nl (RAP4) and create a new script.
  2. Copy the script from the text above into the editor of RAP4.
  3. compile the script. This will succeed.
  4. Open the prototype. This gives the error from the screenshot.
stefjoosten commented 1 year ago

Analysis

I think the enforcement rule simply does an INSERT query in the attribute of s. This deletes the previous contents of the attribute implicitly. However, the enforcement rule should check whether the current content exists and differs, so it can generate the desired error message.

hanjoosten commented 1 year ago

This is an interesting usecase. I wonder if this behavour could be predicted at compiletime. @sjcjoosten , do you have an opinion about this? This has nothing to do with the ENFORCE statement whatsoever. This behaviour could have been specified before as well, as the ENFORCE statement is nothing but syntactical sugar.

sjcjoosten commented 1 year ago

I'm tentatively convinced that this indeed has nothing to do with the ENFORCE statement: if we use the exec-engine, we are telling the system to take a certain action, like inserting or overwriting something, and we get a certain run-time behavior. There's another situation just like this related to defaults which I mentioned earlier: https://github.com/AmpersandTarski/Ampersand/issues/1189#issuecomment-913858435_

Regardless, an insert of a pair (a,b) in a relation containing (a,c) that should be UNI should give an error if c≠b.

If updates of UNI relations are desired, there should be a separate exec-engine command for such updates.

sjcjoosten commented 1 year ago

I wonder if this behavior could be predicted at compiletime.

Not sure what you mean by this, but there's already an SQL UPDATE statement generated, causing this.