on dev help sign in
unNull, simplify Grouping kind, simplify aggregates, test
5f4bafeEitan Chatav
squeel-postgresql/src/Squeel/PostgreSQL/Schema.hs+1−1
@@ -172,7 +172,7 @@ type family Join xs ys where
172
172
173data Grouping
173data Grouping
174 = Ungrouped
174 = Ungrouped
175− | Grouped [(Symbol,(Symbol,ColumnType))]
175+ | Grouped [(Symbol,Symbol)]
176
176
177class TableColumn table column expression where
177class TableColumn table column expression where
178 (&.) :: Alias table -> Alias column -> expression
178 (&.) :: 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)
88def :: Expression params '[] grouping ('Optional (nullity ty))
88def :: Expression params '[] grouping ('Optional (nullity ty))
89def = UnsafeExpression "DEFAULT"
89def = UnsafeExpression "DEFAULT"
90
90
91−notDef
91+unDef
92 :: Expression params '[] grouping ('Required (nullity ty))
92 :: Expression params '[] grouping ('Required (nullity ty))
93 -> Expression params '[] grouping ('Optional (nullity ty))
93 -> Expression params '[] grouping ('Optional (nullity ty))
94−notDef = UnsafeExpression . renderExpression
94+unDef = UnsafeExpression . renderExpression
95
95
96null :: Expression params tables grouping (optionality ('Null ty))
96null :: Expression params tables grouping (optionality ('Null ty))
97null = UnsafeExpression "NULL"
97null = UnsafeExpression "NULL"
98
98
99+unNull
100+ :: Expression params tables grouping (optionality ('NotNull ty))
101+ -> Expression params tables grouping (optionality ('Null ty))
102+unNull = UnsafeExpression . renderExpression
103+
99coalesce
104coalesce
100 :: [Expression params tables grouping ('Required ('Null x))]
105 :: [Expression params tables grouping ('Required ('Null x))]
101 -> Expression params tables grouping ('Required ('NotNull x))
106 -> Expression params tables grouping ('Required ('NotNull x))
@@ -371,46 +376,51 @@ renderSortExpression = \case
371 Asc expression -> renderExpression expression <> " ASC"
376 Asc expression -> renderExpression expression <> " ASC"
372 Desc expression -> renderExpression expression <> " DESC"
377 Desc expression -> renderExpression expression <> " DESC"
373
378
374−data Aggregate (ty0 :: ColumnType) (ty1 :: ColumnType) =
379+unsafeAggregate
375− UnsafeAggregate { renderAggregate :: ByteString }
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, ")"]
376
385
377sum_
386sum_
378 :: PGNum ty
387 :: PGNum ty
379− => Aggregate ('Required (nullity ty)) ('Required (nullity ty))
388+ => Expression params tables 'Ungrouped ('Required (nullity ty))
380−sum_ = UnsafeAggregate "sum"
389+ -> Expression params tables ('Grouped distincts) ('Required (nullity ty))
390+sum_ = unsafeAggregate "sum"
381
391
382class (KnownSymbol table, KnownSymbol column)
392class (KnownSymbol table, KnownSymbol column)
383− => GroupedBy table column distincts ty where
393+ => GroupedBy table column distincts where
384 getGroup
394 getGroup
385 :: (HasTable table tables columns, HasColumn column columns ty)
395 :: (HasTable table tables columns, HasColumn column columns ty)
386 => Alias table
396 => Alias table
387 -> Alias column
397 -> Alias column
388 -> Expression params tables ('Grouped distincts) ty
398 -> 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)
389
408
390instance
409instance
391− ( HasTable table tables columns
410+ ( tables ~ '[table ::: columns]
392 , HasColumn column columns ty
411 , HasColumn column columns ty
393− , GroupedBy table column distincts ty
412+ , GroupedBy table column distincts
394− ) => TableColumn table column
413+ ) => IsLabel column
395 (Expression params tables ('Grouped distincts) ty) where
414 (Expression params tables ('Grouped distincts) ty) where
396− (&.) = getGroup
415+ fromLabel p = getGroup (Alias (proxy# :: Proxy# table)) (Alias p)
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
406
416
407instance
417instance
408 ( HasTable table tables columns
418 ( HasTable table tables columns
409− , HasColumn column columns ty0
419+ , HasColumn column columns ty
410− , Aggregated table column distincts ty
420+ , GroupedBy table column distincts
411 ) => TableColumn table column
421 ) => TableColumn table column
412− (Aggregate ty0 ty -> Expression params tables ('Grouped distincts) ty) where
422+ (Expression params tables ('Grouped distincts) ty) where
413− (&.) = getAggregate
423+ (&.) = getGroup
414
424
415{-----------------------------------------
425{-----------------------------------------
416tables
426tables
@@ -507,19 +517,25 @@ renderTableReference = \case
507 , renderExpression on
517 , renderExpression on
508 ]
518 ]
509
519
510−data By tables tabcolty where
520+data By
521+ (tables :: [(Symbol,[(Symbol,ColumnType)])])
522+ (tabcol :: (Symbol,Symbol)) where
511 By
523 By
512 :: (HasTable table tables columns, HasColumn column columns ty)
524 :: (HasTable table tables columns, HasColumn column columns ty)
513− => Alias table
514− -> Alias column
525+ => (Alias table, Alias column)
515− -> By tables (table ::: (column ::: ty))
526+ -> By tables '(table, column)
516−
527+
528+by
529+ :: ( KnownSymbol table
530+ , tables ~ '[table ::: columns]
517−instance (HasTable table tables columns, HasColumn column columns ty)
531+ , HasColumn column columns ty
532+ )
533+ => Alias column
518− => TableColumn table column (By tables (table ::: (column ::: ty))) where
534+ -> By tables '(table, column)
519− (&.) = By
535+by column = By (Alias (proxy# :: Proxy# (table :: Symbol)), column)
520
536
521renderBy :: By tables tabcolty -> ByteString
537renderBy :: By tables tabcolty -> ByteString
522−renderBy (By table column) = renderAlias table <> "." <> renderAlias column
538+renderBy (By (table, column)) = renderAlias table <> "." <> renderAlias column
523
539
524data GroupByClause tables grouping where
540data GroupByClause tables grouping where
525 NoGroups :: GroupByClause tables 'Ungrouped
541 NoGroups :: GroupByClause tables 'Ungrouped
squeel-postgresql/test/Squeel/PostgreSQL/StatementSpec.hs+14
@@ -79,6 +79,20 @@ spec = do
79 statement = selectStar
79 statement = selectStar
80 (from (Table (#table1 `As` #table1)) & offset 1 & offset 2)
80 (from (Table (#table1 `As` #table1)) & offset 1 & offset 2)
81 statement `queryRenders` "SELECT * FROM table1 AS table1 OFFSET 3;"
81 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);"
82 it "correctly renders simple INSERTs" $ do
96 it "correctly renders simple INSERTs" $ do
83 let
97 let
84 statement :: Manipulation Tables '[] '[]
98 statement :: Manipulation Tables '[] '[]