dylex / postgresql-typed

Haskell PostgreSQL library with compile-time type inference
http://hackage.haskell.org/package/postgresql-typed
Other
83 stars 12 forks source link

Multidimensional Arrays #15

Open RobertFischer opened 6 years ago

RobertFischer commented 6 years ago

I've gotten to the point where I'd like to store a list-of-lists ([(StrictText,StritctText)] -> TEXT[][]), but then I stumbled across the sad comment that multidimensional arrays are not currently supported. What would it take to implement them? If you're willing to give me some guidance and point me in the right direction, I'm happy to take a swing at implementing it.

dylex commented 6 years ago

Implementing them is theoretically not too hard, but there are a few conceptual decisions to be made first, which was where I got stuck. Mainly around how to encode the dimensionality.

One option is to do it all dynamically at run-time. This requires coming up with some more complex type for PGArray (or a new PGMultidimArray type), in the simplest case like [Either (PGArray a) (Maybe a)]. Then we just pass through whatever we get. In some ways this matches the actual postgresql implementation of arrays, which completely ignores any specified dimensions. My main objection to this is just that it's cumbersome. The type is not quite right, though: postgresql arrays can only be rectangular. Is it worth pulling in additional dependencies to represent the proper nd-array?

Another option that better respects the SQL syntax is to encode the dimensionality (and even size) into the type itself. This gets a bit messy, and enforces more consistency that actualy exists, though it might be nice for some applications.

Ultimately my old-school database normalization sense kicked in that really people shouldn't be using things like multidimensional arrays in SQL to begin with, and if people needed structured data they were more likely to use JSON anyway, and thus I never decided anything.

So, if you have a use-case, perhaps it can inform this. (If your use case is a list-of-tuples, it may also be possible to use a record[] type, though there may also be some implementation gaps there.)

RobertFischer commented 6 years ago

Yeah, I feel your old-school DB normalization sense: I feel gross doing what I'm doing, but the data isn't really a distinct entity, and so it also feels gross to put it somewhere technically divorced from its context.

I've actually decided on having two fields, both of which are TEXT[]: one for keys, and one for values. I'll just zip them together as necessary.