You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If you use a comparison operator on a Maybe value, there is nothing stopping a null getting into your conditionals if the values going into >=. are actually Nothing. This may wind up ruining your day or otherwise creating ... funny runtime bugs, since you create a NULL in a Value Bool, which is not supposed to be there.
I think that in the current type signatures, val . Just is probably universally an invitation for bugs with the sole exception of if the result goes into ||..
Real-world example
If you write a query like this and omit the isNothing check you can cause this issue:
-- | Schedule to accept calls
ScheduleEntry sql=schedule_entries
-- | Time at which this schedule starts applying
startDate Day Maybe
endDate Day Maybe
-- | Start time in each day that this schedule applies
startHours Int
startMins Int
endHours Int
endMins Int
applicableRules::LocalTime->SqlQuery (SqlExpr (EntityScheduleEntry))
applicableRules ts =do
sched <- from $ table @ScheduleEntrylet day = localDay ts
letTimeOfDay {todHour, todMin} = localTimeOfDay ts
where_ $ isNothing sched.startDate ||. (val .Just) day >=. sched.startDate
where_ $ isNothing sched.endDate ||. (val .Just) day <=. sched.endDate
where_ $ val todHour >=. sched.startHours &&. val todHour <=. sched.endHours
where_ $ val todMin >=. sched.startMins &&. val todMin <=. sched.endMins
pure sched
This could possibly be fixed in a way that only breaks suspicious uses (although my condolences extend to anyone with a large codebase dealing with migrating this; probably would want to keep around the old buggy signatures for compat under a different name, so you could just replace all usages and migrate piecewise):
A note about a consequent API change to fixing all the boolean operators to properly model tristate: you would need to fix stuff like
q =
from $ table @Catgirls`leftJoin` table @Catears`on` (\(cg :& earb) -> just cg.id==. earb.owner)
where owner may be null, so you use just in this comparison. Under the suggested fix, this comparison would now return a Maybe, which is totally reasonable as an on clause input; it will do the right thing if it gets a null, but the on function would have to be adjusted to accept this.
I am increasingly thinking that perhaps the sound comparison operators should be introduced into a new module that would become part of the default set when Experimental is actually stabilized, and then you could migrate module by module, because I can already see how much this might suck for industry code.
If you use a comparison operator on a Maybe value, there is nothing stopping a null getting into your conditionals if the values going into
>=.
are actually Nothing. This may wind up ruining your day or otherwise creating ... funny runtime bugs, since you create aNULL
in aValue Bool
, which is not supposed to be there.I think that in the current type signatures,
val . Just
is probably universally an invitation for bugs with the sole exception of if the result goes into||.
.Real-world example
If you write a query like this and omit the
isNothing
check you can cause this issue:This could possibly be fixed in a way that only breaks suspicious uses (although my condolences extend to anyone with a large codebase dealing with migrating this; probably would want to keep around the old buggy signatures for compat under a different name, so you could just replace all usages and migrate piecewise):
cc @parsonsmatt, I'm unsure if this type level shenanigans is fully sound either
The text was updated successfully, but these errors were encountered: