on dev help sign in
unNull, simplify Grouping kind, simplify aggregates, test
commit5f4bafe79b5a760cd41ae823a7b3b48134220f4e authorEitan Chatav <eitan.chatav@gmail.com> dateTue 8 Aug 2017, 12:56 (9 years ago) parentf152a6c
3 files changed+64−34
squeel-postgresql/src/Squeel/PostgreSQL/Schema.hs+1−1 squeel-postgresql/src/Squeel/PostgreSQL/Statement.hs+49−33 squeel-postgresql/test/Squeel/PostgreSQL/StatementSpec.hs+14
squeel-postgresql/src/Squeel/PostgreSQL/Schema.hs+1−1
@@ -172,7 +172,7 @@ type family Join xs ys where
172172
173173data Grouping
174174 = Ungrouped
175− | Grouped [(Symbol,(Symbol,ColumnType))]
175+ | Grouped [(Symbol,Symbol)]
176176
177177class TableColumn table column expression where
178178 (&.) :: Alias table -> Alias column -> expression
squeel-postgresql/src/Squeel/PostgreSQL/Statement.hs+49−33
@@ -88,14 +88,19 @@ instance (HasTable table tables columns, HasColumn column columns ty)
8888def :: Expression params '[] grouping ('Optional (nullity ty))
8989def = UnsafeExpression "DEFAULT"
9090
91−notDef
91+unDef
9292 :: Expression params '[] grouping ('Required (nullity ty))
9393 -> Expression params '[] grouping ('Optional (nullity ty))
94−notDef = UnsafeExpression . renderExpression
94+unDef = UnsafeExpression . renderExpression
9595
9696null :: Expression params tables grouping (optionality ('Null ty))
9797null = UnsafeExpression "NULL"
9898
99+unNull
100+ :: Expression params tables grouping (optionality ('NotNull ty))
101+ -> Expression params tables grouping (optionality ('Null ty))
102+unNull = UnsafeExpression . renderExpression
103+
99104coalesce
100105 :: [Expression params tables grouping ('Required ('Null x))]
101106 -> Expression params tables grouping ('Required ('NotNull x))
@@ -371,46 +376,51 @@ renderSortExpression = \case
371376 Asc expression -> renderExpression expression <> " ASC"
372377 Desc expression -> renderExpression expression <> " DESC"
373378
374−data Aggregate (ty0 :: ColumnType) (ty1 :: ColumnType) =
375− UnsafeAggregate { renderAggregate :: ByteString }
379+unsafeAggregate
380+ :: ByteString
381+ -> Expression params tables 'Ungrouped xty
382+ -> Expression params tables ('Grouped distincts) yty
383+unsafeAggregate fun x = UnsafeExpression $ mconcat
384+ [fun, "(", renderExpression x, ")"]
376385
377386sum_
378387 :: PGNum ty
379− => Aggregate ('Required (nullity ty)) ('Required (nullity ty))
380−sum_ = UnsafeAggregate "sum"
388+ => Expression params tables 'Ungrouped ('Required (nullity ty))
389+ -> Expression params tables ('Grouped distincts) ('Required (nullity ty))
390+sum_ = unsafeAggregate "sum"
381391
382392class (KnownSymbol table, KnownSymbol column)
383− => GroupedBy table column distincts ty where
393+ => GroupedBy table column distincts where
384394 getGroup
385395 :: (HasTable table tables columns, HasColumn column columns ty)
386396 => Alias table
387397 -> Alias column
388398 -> Expression params tables ('Grouped distincts) ty
399+ getGroup table column = UnsafeExpression $
400+ renderAlias table <> "." <> renderAlias column
401+instance {-# OVERLAPPING #-} (KnownSymbol table, KnownSymbol column)
402+ => GroupedBy table column '[ '(table,column)]
403+instance {-# OVERLAPPABLE #-}
404+ ( KnownSymbol table
405+ , KnownSymbol column
406+ , GroupedBy table column distincts
407+ ) => GroupedBy table column (tabcol ': distincts)
389408
390409instance
391− ( HasTable table tables columns
410+ ( tables ~ '[table ::: columns]
392411 , HasColumn column columns ty
393− , GroupedBy table column distincts ty
394− ) => TableColumn table column
412+ , GroupedBy table column distincts
413+ ) => IsLabel column
395414 (Expression params tables ('Grouped distincts) ty) where
396− (&.) = getGroup
397−
398−class (KnownSymbol table, KnownSymbol column)
399− => Aggregated table column distincts ty where
400− getAggregate
401− :: (HasTable table tables columns, HasColumn column columns ty0)
402− => Alias table
403− -> Alias column
404− -> Aggregate ty0 ty
405− -> Expression params tables ('Grouped distincts) ty
415+ fromLabel p = getGroup (Alias (proxy# :: Proxy# table)) (Alias p)
406416
407417instance
408418 ( HasTable table tables columns
409− , HasColumn column columns ty0
410− , Aggregated table column distincts ty
419+ , HasColumn column columns ty
420+ , GroupedBy table column distincts
411421 ) => TableColumn table column
412− (Aggregate ty0 ty -> Expression params tables ('Grouped distincts) ty) where
413− (&.) = getAggregate
422+ (Expression params tables ('Grouped distincts) ty) where
423+ (&.) = getGroup
414424
415425{-----------------------------------------
416426tables
@@ -507,19 +517,25 @@ renderTableReference = \case
507517 , renderExpression on
508518 ]
509519
510−data By tables tabcolty where
520+data By
521+ (tables :: [(Symbol,[(Symbol,ColumnType)])])
522+ (tabcol :: (Symbol,Symbol)) where
511523 By
512524 :: (HasTable table tables columns, HasColumn column columns ty)
513− => Alias table
514− -> Alias column
515− -> By tables (table ::: (column ::: ty))
516−
517−instance (HasTable table tables columns, HasColumn column columns ty)
518− => TableColumn table column (By tables (table ::: (column ::: ty))) where
519− (&.) = By
525+ => (Alias table, Alias column)
526+ -> By tables '(table, column)
527+
528+by
529+ :: ( KnownSymbol table
530+ , tables ~ '[table ::: columns]
531+ , HasColumn column columns ty
532+ )
533+ => Alias column
534+ -> By tables '(table, column)
535+by column = By (Alias (proxy# :: Proxy# (table :: Symbol)), column)
520536
521537renderBy :: By tables tabcolty -> ByteString
522−renderBy (By table column) = renderAlias table <> "." <> renderAlias column
538+renderBy (By (table, column)) = renderAlias table <> "." <> renderAlias column
523539
524540data GroupByClause tables grouping where
525541 NoGroups :: GroupByClause tables 'Ungrouped
squeel-postgresql/test/Squeel/PostgreSQL/StatementSpec.hs+14
@@ -79,6 +79,20 @@ spec = do
7979 statement = selectStar
8080 (from (Table (#table1 `As` #table1)) & offset 1 & offset 2)
8181 statement `queryRenders` "SELECT * FROM table1 AS table1 OFFSET 3;"
82+ it "should render GROUP BY and HAVING clauses" $ do
83+ let
84+ statement :: Query Tables '[] SumAndCol1
85+ statement = select
86+ (sum_ #col2 `As` #sum :* #col1 `As` #col1 :* Nil)
87+ ( from (Table (#table1 `As` #table1))
88+ & group (by #col1 :* Nil)
89+ & having ((#col1 + sum_ #col2) >* 1) )
90+ statement `queryRenders`
91+ "SELECT\
92+ \ sum(col2) AS sum, table1.col1 AS col1\
93+ \ FROM table1 AS table1\
94+ \ GROUP BY table1.col1\
95+ \ HAVING ((table1.col1 + sum(col2)) > 1);"
8296 it "correctly renders simple INSERTs" $ do
8397 let
8498 statement :: Manipulation Tables '[] '[]