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
I noticed that if you try to insert a UTCTime with a negative year, it fails even though PostgreSQL does handle this case. It seems that we are generating invalid syntax.
On PostgresSQL 15, the error is:
SqlExecutionError
{ sqlExecutionErrorExecStatus = Just FatalError
, sqlExecutionErrorMessage = "ERROR: invalid input syntax for type timestamp with time zone: \"-0001-01-01 00:00:00+00\"\n"
, sqlExecutionErrorSqlState = Just "22007"
, sqlExecutionErrorSqlQuery = "INSERT INTO \"foo\" (\"id\",\"name\",\"birth\") VALUES ($1,$2,$3)"
}
I don't think we can actually map all UTCTimes to SQL, since PostgreSQL has a limit on the year, but the time library uses an Integer, which is unbounded.
One way to improve handling of UTCTime specifically, might be to use the function make_timestamptz(year, month, ...), which explicitly states in its documentation that it supports negative years. Or maybe we just don't wanna support those? Either way, I think the choice should be documented.
So I propose we use Hedgehog to run property tests for all sqlTypes, to see which ones round trip and which ones don't. Then, we can attach documentation to the relevant SqlTypes and FieldDefinitions, with a comment warning that they are partial and will work for only a certain range. We can also test whether the ordering in SQL works the same as in Haskell.
The text was updated successfully, but these errors were encountered:
Great catch! I don't think there is a straightforward way to use make_timestamptz here because we can't put a function call in parameter. Instead we should remove the leading - and append BC to the timestamp, since negative years represent B.C.E. years in PostgreSQL.
It is unfortunate that we can't encode all Haskell UTCTimes in SQL. The current implementation requires converting a Haskell value to a SqlValue to be infallible, i.e. we need a function UTCTime -> SqlValue, as opposed to decoding where we can say SqlValue -> Either String UTCTime.
We could introduce a newtype wrapper and conversion functions around UTCTime that restricts the timestamp to the range allowed by PostgreSQL. That would push the range validation of the UTCTime out to the caller.
I noticed that if you try to insert a UTCTime with a negative year, it fails even though PostgreSQL does handle this case. It seems that we are generating invalid syntax.
On PostgresSQL 15, the error is:
Reproduction program
I don't think we can actually map all UTCTimes to SQL, since PostgreSQL has a limit on the year, but the
time
library uses anInteger
, which is unbounded.One way to improve handling of UTCTime specifically, might be to use the function
make_timestamptz(year, month, ...)
, which explicitly states in its documentation that it supports negative years. Or maybe we just don't wanna support those? Either way, I think the choice should be documented.So I propose we use Hedgehog to run property tests for all sqlTypes, to see which ones round trip and which ones don't. Then, we can attach documentation to the relevant SqlTypes and FieldDefinitions, with a comment warning that they are partial and will work for only a certain range. We can also test whether the ordering in SQL works the same as in Haskell.
The text was updated successfully, but these errors were encountered: