@@ -1,200 +0,0 @@
1−{-# language ApplicativeDo #-}
2−{-# language LambdaCase #-}
3−
4−{-# options -fno-warn-name-shadowing #-}
5−
6−module Rel8.Query.Optimize
7− ( optimize
8− )
9−where
10−
11−-- base
12−import Control.Applicative
13−import Data.Functor.Identity
14−import Prelude
15−
16−-- opaleye
17−import Opaleye.Internal.HaskellDB.PrimQuery
18−import Opaleye.Internal.PrimQuery
19−
20−
21−optimize :: PrimQuery' a -> PrimQuery' a
22−optimize =
23− transformOf primQuery optimisePredicates
24−
25−
26−primQuery
27− :: Applicative f
28− => ( PrimQuery' a -> f ( PrimQuery' a ) ) -> PrimQuery' a -> f ( PrimQuery' a )
29−primQuery f = \case
30− Aggregate bindingsAndPrimExpr primQuery -> do
31− primQuery <- f primQuery
32−
33− return ( Aggregate bindingsAndPrimExpr primQuery )
34−
35− DistinctOnOrderBy maybePrimExprs orderExprs primQuery -> do
36− primQuery <- f primQuery
37−
38− return ( DistinctOnOrderBy maybePrimExprs orderExprs primQuery )
39−
40− Limit limitOp primQuery -> do
41− primQuery <- f primQuery
42−
43− return ( Limit limitOp primQuery )
44−
45− Join joinType primExpr bindingsA bindingsB primQueryA primQueryB -> do
46− primQueryA <- f primQueryA
47− primQueryB <- f primQueryB
48−
49− return ( Join joinType primExpr bindingsA bindingsB primQueryA primQueryB )
50−
51− Exists bool primQueryA primQueryB -> do
52− primQueryA <- f primQueryA
53− primQueryB <- f primQueryB
54−
55− return ( Exists bool primQueryA primQueryB )
56−
57− Binary binOp primQueries -> do
58− primQueries <- both f primQueries
59−
60− return ( Binary binOp primQueries )
61−
62− Label label primQuery -> do
63− primQuery <- f primQuery
64−
65− return ( Label label primQuery )
66−
67− other ->
68− pure other
69−
70−
71−optimisePredicates :: PrimQuery' a -> PrimQuery' a
72−optimisePredicates = \case
73− Join joinType predicate bindingsA bindingsB primQueryA primQueryB ->
74− Join joinType ( nullIsFalse predicate ) bindingsA bindingsB primQueryA primQueryB
75−
76− other ->
77− other
78−
79−
80−nullIsFalse :: PrimExpr -> PrimExpr
81−nullIsFalse =
82− rewriteOf primExprs simplifyCaseAnalysis
83−
84− where
85−
86− simplifyCaseAnalysis = \case
87− CaseExpr [ ( UnExpr OpIsNull _, ConstExpr ( BoolLit False ) ) ] notNullBranch ->
88− Just notNullBranch
89−
90− CaseExpr [ ( UnExpr OpIsNull x, UnExpr OpIsNull y ) ] notNullBranch ->
91− Just
92− ( BinExpr
93− (:||)
94− ( BinExpr (:&&) ( UnExpr OpIsNull x ) ( UnExpr OpIsNull y ) )
95− notNullBranch
96− )
97−
98− _ ->
99− Nothing
100−
101−
102−
103−-- | Traverse all immediate 'PrimExpr's
104−primExprs :: Applicative f => ( PrimExpr -> f PrimExpr ) -> PrimExpr -> f PrimExpr
105−primExprs f = \case
106− AttrExpr ( Symbol string tag ) ->
107− pure ( AttrExpr ( Symbol string tag ) )
108−
109− BaseTableAttrExpr attribute ->
110− pure ( BaseTableAttrExpr attribute )
111−
112− CompositeExpr primExpr attribute -> do
113− primExpr <- f primExpr
114−
115− return ( CompositeExpr primExpr attribute )
116−
117− BinExpr binOp a b -> do
118− a <- f a
119− b <- f b
120−
121− return ( BinExpr binOp a b )
122−
123− UnExpr unOp primExpr -> do
124− primExpr <- f primExpr
125−
126− return ( UnExpr unOp primExpr )
127−
128− AggrExpr aggrDistinct aggrOp primExpr orderExprs -> do
129− aggrOp <- aggrOpPrimExprs f aggrOp
130− primExpr <- f primExpr
131− orderExprs <- traverse ( orderExprPrimExprs f ) orderExprs
132−
133− return ( AggrExpr aggrDistinct aggrOp primExpr orderExprs )
134−
135− ConstExpr l ->
136− pure ( ConstExpr l )
137−
138− CaseExpr cases def -> do
139− cases <- traverse ( both f ) cases
140− def <- f def
141−
142− return ( CaseExpr cases def )
143−
144− other ->
145− pure other
146−
147−
148−
149−aggrOpPrimExprs :: Applicative f => ( PrimExpr -> f PrimExpr ) -> AggrOp -> f AggrOp
150−aggrOpPrimExprs f = \case
151− AggrStringAggr primExpr -> do
152− primExpr <- f primExpr
153−
154− return ( AggrStringAggr primExpr )
155−
156− other ->
157− pure other
158−
159−
160−orderExprPrimExprs :: Applicative f => ( PrimExpr -> f PrimExpr ) -> OrderExpr -> f OrderExpr
161−orderExprPrimExprs f ( OrderExpr orderOp primExpr ) = do
162− primExpr <- f primExpr
163−
164− return ( OrderExpr orderOp primExpr )
165−
166−
167−-- | Traverse both sides of a homogeneous tuple.
168−both :: Applicative f => ( t -> f b ) -> ( t, t ) -> f ( b, b )
169−both f ( a,b ) =
170− liftA2 (,) ( f a ) ( f b )
171−
172−
173−rewriteOf
174− :: ( ( a -> Identity a ) -> a -> Identity a )
175− -> ( a -> Maybe a ) -> a -> a
176−rewriteOf l f =
177− go where
178−
179− go = transformOf l ( \x -> maybe x go ( f x ) )
180−
181−
182−transformOf
183− :: ( ( a -> Identity a ) -> a -> Identity a )
184− -> ( a -> a )
185− -> a
186− -> a
187−{-# inline transformOf #-}
188−transformOf l f = go where
189−
190− go =
191− f . over l go
192−
193−
194−over
195− :: ( ( s -> Identity t ) -> a -> Identity b )
196− -> ( s -> t )
197− -> a
198− -> b
199−over l f =
200− runIdentity . l (Identity . f)