@@ -15,26 +15,26 @@ where
1515import Prelude
1616
1717-- opaleye
18−import qualified Opaleye.Internal.Join as Opaleye
18+import qualified Opaleye.Internal.PackMap as Opaleye
1919import qualified Opaleye.Internal.PrimQuery as Opaleye
20+import qualified Opaleye.Internal.QueryArr as Opaleye
21+import qualified Opaleye.Internal.Tag as Opaleye
2022
2123-- rel8
2224import Rel8.Expr ( Expr )
2325import Rel8.Expr.Bool ( boolExpr, not_ )
2426import Rel8.Expr.Eq ( (==.) )
25−import Rel8.Expr.Opaleye ( toColumn, toPrimExpr )
27+import Rel8.Expr.Opaleye ( toPrimExpr, traversePrimExpr )
2628import Rel8.Expr.Serialize ( litExpr )
2729import Rel8.Query ( Query )
2830import Rel8.Query.Filter ( where_ )
2931import Rel8.Query.Maybe ( optional )
3032import Rel8.Query.Opaleye ( zipOpaleyeWith )
31−import Rel8.Table ( Table )
3233import Rel8.Table.Either ( EitherTable( EitherTable ) )
3334import Rel8.Table.Maybe ( MaybeTable( MaybeTable ), isJustTable )
34−import Rel8.Table.Opaleye ( unpackspec )
35−import Rel8.Table.Tag ( Tag(..) )
35+import Rel8.Table.Tag ( Tag(..), fromExpr )
3636import Rel8.Table.These
37− ( TheseTable( TheseTable )
37+ ( TheseTable( TheseTable, here, there )
3838 , hasHereTable, hasThereTable
3939 , isThisTable, isThatTable, isThoseTable
4040 )
@@ -42,17 +42,28 @@ import Rel8.Type.Tag ( EitherTag( IsLeft, IsRight ) )
4242
4343
4444-- | Corresponds to a @FULL OUTER JOIN@ between two queries.
45−alignBy :: (Table Expr a, Table Expr b)
45+alignBy :: ()
4646 => (a -> b -> Expr Bool)
4747 -> Query a -> Query b -> Query (TheseTable a b)
48−alignBy condition as bs =
49− uncurry TheseTable <$> zipOpaleyeWith fullOuterJoin as bs
50− where
51− fullOuterJoin a b =
52− Opaleye.joinExplicit unpackspec unpackspec pure pure full a b on
53− where
54− full = Opaleye.FullJoin
55− on = toColumn . toPrimExpr . uncurry condition
48+alignBy condition = zipOpaleyeWith $ \left right -> Opaleye.QueryArr $ \i -> case i of
49+ (_, input, tag) -> (tab, join', tag''')
50+ where
51+ (ma, left', tag') = Opaleye.runSimpleQueryArr (pure <$> left) ((), tag)
52+ (mb, right', tag'') = Opaleye.runSimpleQueryArr (pure <$> right) ((), tag')
53+ MaybeTable Tag {expr = hasHere} a = ma
54+ MaybeTable Tag {expr = hasThere} b = mb
55+ (hasHere', lbindings) = Opaleye.run $ do
56+ traversePrimExpr (Opaleye.extractAttr "hasHere" tag'') hasHere
57+ (hasThere', rbindings) = Opaleye.run $ do
58+ traversePrimExpr (Opaleye.extractAttr "hasThere" tag'') hasThere
59+ tag''' = Opaleye.next tag''
60+ join = Opaleye.Join Opaleye.FullJoin on lbindings rbindings left' right'
61+ where
62+ on = toPrimExpr $ condition a b
63+ ma' = MaybeTable (fromExpr hasHere') a
64+ mb' = MaybeTable (fromExpr hasThere') b
65+ tab = TheseTable {here = ma', there = mb'}
66+ join' = Opaleye.times input join
5667
5768
5869-- | Filter 'TheseTable's, keeping only 'thisTable's and 'thoseTable's.