Closed benjaminjkraft closed 6 years ago
cc @betaveros I think you were interested in hearing about this.
Do we really need the flexibility of storing a DSL that can express arbitrarily complicated boolean conditions in terms of its atoms in the database?
Certainly not the way they're used now! Replacing lunch constraints with something a lot less general would also be a valid solution to this problem, and definitely a worthwhile undertaking. Or even something almost as general but less Clever -- e.g. a simple text or JSON DSL for the conditions rather than storing them as database structures would have avoided this issue as well as making them much easier to read. But probably if you're replacing them wholesale, just do it right and don't make it general at all.
The lunch constraint generator generates a set of
ScheduleConstraint
based on the selections in the interface and the program's timeblocks; each consists of twoBooleanExpression
s, a condition and a requirement, which consist of an RPN-style stack ofBooleanToken
s, so for example[ScheduleTestOccupied(timeblock_1), ScheduleTestOccupied(timeblock_2), '||']
would be true if the user has a class intimeblock_1
ortimeblock_2
. The ordering of the stack is stored in theseq
field of theBooleanToken
.For some reason, the lunch constraint generator hasn't always been setting distinct
seq
objects on each of itsBooleanToken
s, such that their ordering is not well-defined. In the past, they seem to somehow have always come out in the right order, I'm guessing because the database broke ties byid
, which happened to be the intended ordering. But for MIT ESP Spark 2018, possibly because of a postgres upgrade, they didn't, which caused an expression like the above to always evaluate to False, which as the requirement meant the constraint not satisfied when it should have been.The fix will be to correctly set the
seq
on each token. I'm not totally sure why it's not getting set correctly, but it seems that a simple OR like the above consistently results in all threeseq
s being 0, whereas really the OR should have a strictly higherseq
.