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

`IDENT` statement is not implemented as the RULE it is syntax sugar for. #950

Open RieksJ opened 5 years ago

RieksJ commented 5 years ago

Using Ampersand-v3.16.0 [feature/578-navbar:c3acfc3d1], there is no problem in compiling the following script:

CONTEXT "Issue #950"

IDENT BFs: BF(bfOrg,bfName)

bfOrg  :: BF * Org  [UNI]
bfName :: BF * Name [UNI]

POPULATION BF CONTAINS  [ "BF_Fin", "BF_V1622" ]

ENDCONTEXT

I would expect that after installation, the IDENT statement would produce an invariant error, because both BFs, i.e. BF_Fin and BF_V1622, have the same (missing) Org and the same (missing) Name, as is shown when inspecting the database:

afbeelding

Notes:

hanjoosten commented 5 years ago

In all the databases I know, a primary key implies that all fields to be not null. Having expressions in the IDENT that are not TOT will in those databases either be forbidden OR they will only work when all fields are not null. See for example these links for Oracle, MariaDB.

On stackoverflow, I found this excellent explanation on why null values are disallowed in most databases: Null isn't comparable. It isn't a value. It just is Nothing.

To fix this, we need need to check that all expressions in an IDENT statement are TOT.

RieksJ commented 5 years ago

This is not about primary keys. This is about the IDENT statement having been defined as syntax sugar for a specified rule, and it simply isn't doing that. Several years ago, @sjcjoosten told me that IDENT Xs: X(r,s,...) is syntax sugar for RULE Xs: r<>r~ /\ s<>s~ ... |- X. I recall that this was the case back then, but somehow this has fallen prey to bitrot. I'm confident that @stefjoosten would agree that this is the definition of IDENT.

hanjoosten commented 5 years ago

Ok. In that case, there is no error. Check the rule's semantics.

RieksJ commented 5 years ago

I do not get an error if I compile the following script:

CONTEXT "Issue #950"

IDENT BFs: BF(bfOrg,bfName)

bfOrg  :: BF * Org  [UNI]
bfName :: BF * Name [UNI]

POPULATION BF CONTAINS  [ "BF_Fin", "BF_V1622" ]

ENDCONTEXT

However, I do get an error if I compile the following script:

CONTEXT "Issue #950"

RULE BFs: bfOrg<>bfOrg~ /\ bfName<>bfName~ |- I[BF]

bfOrg  :: BF * Org  [UNI]
bfName :: BF * Name [UNI]

POPULATION BF CONTAINS  [ "BF_Fin", "BF_V1622" ]

ENDCONTEXT

To me, this implies that IDENT doesn't work as specified. Please fix that

hanjoosten commented 5 years ago

In databases like MySQL and MariaDB, this cannot be implemented by using a UNIQUE INDEX, as NULL values never are considered to be equal. If there is a way to implement this in another way, I expect that to be non-performant.

github-actions[bot] commented 6 months ago

This issue is stale because it has been open 5 years with no activity. Remove stale label or comment or this will be closed in 30 days.

hanjoosten commented 6 months ago

@stefjoosten , is this an error in the semantics of IDENT? Or is there something wrong in the implementation?