Open tomjaguarpaw opened 7 years ago
I had an Opaleye bug filed about this issue:
https://github.com/tomjaguarpaw/haskell-opaleye/issues/250#issuecomment-265146334
I can add type casts to all literal strings but I'd rather not if at all possible.
It's worth noting that if you try to create a table from a query without casting the type directly in PostgreSQL, you get a warning:
guest=> create temporary table foo as select 'hello' as x;
WARNING: column "x" has type "unknown"
DETAIL: Proceeding with relation creation anyway.
SELECT 1
guest=> \d foo
Table "pg_temp_2.foo"
Column | Type | Modifiers
--------+---------+-----------
x | unknown |
It is also worth noting that PostgreSQL won't let you do comparisons when the types are not comparable:
guest=> create temporary table bar as select 'hello' :: text as x;
SELECT 1
guest=> select * from foo join bar using (x);
ERROR: failed to find conversion function from unknown to text
So if PostgreSQL doesn't think they're the same, why should postgresql-simple?
I really don't have a clear idea what the correct design is.
If I were writing a language I wouldn't allow literals whose type was ambiguous or unknown. But we're working with the SQL we've got, not the one we deserve. The question is, would it be more helpful to users of postgresql-simple to guess that it's a UTF8 encoded string and try to decode it anyway, even if its type oid is "unknown"?
I should also point out that postgresql-simple does not support casting a field that has a known type to an incompatible Haskell type. So postgresql-simple's behavior regarding the PostgreSQL unknown type is consistent to me.
foo :: (HasPostgres m) => m [Only Text]
foo = query_ "SELECT now()"
A web handler threw an exception. Details:
Incompatible {errSQLType = "timestamptz", errSQLTableOid = Nothing, errSQLField = "now", errHaskellType = "Text", errMessage = "types incompatible"}
Text types aren't the only type that could potentially be unknown. Dates, intervals, and the number/date/time values of infinity
and -infinity
also look like text types on the surface because they require quotes (and by extension, require inference or casting in order to be treated correctly) in PostgreSQL.
Well, there is an argument for making all postgresql-simple FromField instances compatible with unknown
, taking the optimistic instead of pessimistic route to type checking. An "actual" type error would be more likely to manifest as a parse error or (perhaps less likely) "strange" behavior, but this would also allow postgresql-simple to more easily support the record
type, where we don't have access to type information for the individual record fields. (Note though, that composite types, i.e. explicitly declared record types, don't have this problem)
PostgreSQL's type system often does correspond reasonably well to Haskell's, but there's definitely some issues there as well.
I'm a bit confused why
instance FromField String
can't decode literal strings without a type cast. Is it not possible to make them work?Example: