Comments (10)
Opaleye doesn't support SQL-level tuples (anonymous records) yet, so you can't do quite that, but you can aggregate into two separate arrays and then zip
them on the Haskell side. That is, return something like [(a, [b], [c])]
and then zip the b
s and c
s to get a [(b, c)]
. Does that make sense?
from haskell-opaleye.
That seems simple enough, though would the type of arrayAgg
restrict that from working with nullable fields? I think I might be able to work around that if it's a limitation, but I'm curious if there's a way to do that.
from haskell-opaleye.
Hmm, yes, but that seems like a bug in arrayAgg
. Can you try
arrayAgg_ :: Aggregator (F.Field_ n a) (F.Field (T.SqlArray_ n a))
arrayAgg_ = Opaleye.Internal.Aggregate.makeAggr HPQ.AggrArr
and let me know if that works OK? If so I can add it to Opaleye.
from haskell-opaleye.
Should I need a DefaultFromFields (SqlArray_ 'Nullable sqlType) [Maybe haskellType]
instance? Trying to test it in my own code said it was a missing instance, and I do see there's a Default (Inferrable FromField) (SqlArray_ Nullable sqlType) [Maybe hsType]
instance that looks pretty close, but I don't quite get how they relate to each other.
from haskell-opaleye.
Thanks for reporting all of these omissions regarding nullable fields. It looks like I made a lot of oversights when converting from Column
to Field
!
You are correct that the instance has been incorrectly omitted. Please try adding it back locally with
instance (Typeable b, DefaultFromField a b) =>
DefaultFromField (T.SqlArray_ Nullable a) [Maybe b] where
defaultFromField = fromFieldArrayNullable defaultFromField
I will add this instance in a bugfix release too.
from haskell-opaleye.
The instance issue should be fixed in https://hackage.haskell.org/package/opaleye-0.9.4.0. Let me know if this doesn't solve the problem for you.
from haskell-opaleye.
So I tried using arrayAgg_
as you suggested and it looks like things are working, though my use of it wasn't super extensive. The workaround with the zipping instead of a runSelect
inside of a loop also seemed to work well; I assume the DBMS would rewrite the shared part of the aggregations into a single aggregation, but regardless it sped things from a couple of seconds to close to instantaneous.
from haskell-opaleye.
Nice! I should add arrayAgg_
to Opaleye then.
from haskell-opaleye.
OK, arrayAgg_
is available at https://hackage.haskell.org/package/opaleye-0.9.5.1
from haskell-opaleye.
So if this can be accomplished with the product-profunctors interface instead of lenses it might be worthwhile adding an example to the documentation for arrayAgg_
mentioning the zipping idiom, but even if not I thought mentioning it might be helpful if anyone ends up with the same issue. But I ended up needing to do a large number of such aggregations, and found the easiest way to accomplish them was doing something like
aggregateOf
:: ((Select s -> Select (Field (SqlArray_ n a))) -> w -> m t
-> Lens.Getting (Field_ n a) s (Field_ n a)
-> w
-> m t
aggregateOf l l' = l (aggregate arrayAgg_ . fmap (Lens.view l'))
...
unzippedRows <- pure SomeRow
{ someColumn1 = selectSomeRow
, someColumn2 = selectSomeRow
}
>>= aggregateOf someColumn1Lens someColumn1Lens
>>= aggregateOf someColumn2Lens someColumn2Lens
where selectSomeRow :: Select (SomeRow (Field SqlCol1Field) (Field SqlCol2Field))
. The basic idea is that the SomeRow
datatype contains the select statement to retrieve itself in each field, and aggregateOf
projects out the individual field, aggregates it, and then traverses out the select, so it now contains the list of that row.
It still makes me a touch nervous to trust postgresql to share the work duplicated in each aggregation, but I don't think there's any way to avoid that with the zipping idiom regardless of whether it's abstracted like this or not. I don't know if that concern is really warranted given how thoroughly DBMSes are optimized.
from haskell-opaleye.
Related Issues (20)
- MaybeFields on Table? HOT 7
- Add nullableToMaybeFields HOT 1
- Add newtyped write field example to TutorialBasic
- How to aggregate on selected fields or joining table fields? HOT 10
- Nullable vs MaybeFields HOT 8
- What does Rebind do in `optionalRestrict`? HOT 3
- How to aggregate on MaybeFields? HOT 1
- Is there a cast operator? HOT 4
- Expose unsafeCast from Opaleye.Field
- A default `DefaultFromFields` via a type family?
- Why does the GHC 9.0 Action keep failing? HOT 3
- Respond to Brown Benchmark for Table Types
- Should asc/desc/ascNullsFirst/descNullsLast have a less restrictive type? HOT 3
- Bizarre Haddock formatting on Hackage
- Add a test for `filterWhere`
- What's the best way to improve the readability of large select? HOT 4
- More type safety with same field type in a table HOT 7
- `unsafeCoerceField` does not generate expected `CAST` HOT 1
- disallow `orderAggregate` with `distinctAggregator` HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from haskell-opaleye.