Skip to content

Semantics of aggregation is unclear #22

@karamaan

Description

@karamaan

The semantics of HaskellDB's aggregation operators is very unclear. Let me propose the following example to demonstrate my confusion. It concerns a table whose rows represent people. A person has a family and an age.

import Database.HaskellDB.PrimQuery
import Database.HaskellDB.Query
import Database.HaskellDB.HDBRec
import Database.HaskellDB.DBLayout

data Person = Person
instance FieldTag Person where
  fieldName _ = "person"

data Family = Family
instance FieldTag Family where
  fieldName _ = "family"

data Age = Age
instance FieldTag Age where
  fieldName _ = "age"

family :: Attr Family String
family = mkAttr Family

person :: Attr Person String
person = mkAttr Person

age :: Attr Age Int
age = mkAttr Age

personTable :: Table (RecCons Person String
                  (RecCons Family String
                   (RecCons Age Int RecNil)))
personTable = Table "mytable" [ ("person", AttrExpr "personcol")
                              , ("family", AttrExpr "familycol")
                              , ("age", AttrExpr "agecol") ]

I might want to calculate the total age of everyone in a family. This I do with agesOfFamilies. It returns a query whose rows (ostensibly) pair the family with the total age of everyone in that family.

agesOfFamilies :: Query (Rel
                         (RecCons Family (Expr String)
                          (RecCons Age (Expr Int) RecNil)))
agesOfFamilies = do
  my <- table personTable
  project (family << my!family # age << _sum (my!age))

I can test it with showSql thus:

*Main> putStrLn $ showSql agesOfFamilies 
SELECT familycol as family,
       SUM(agecol) as age
FROM mytable as T1
GROUP BY familycol

which is exactly what I wanted. What happens if I want to project just the age column from this query?

justAgesOfFamilies :: Query (Rel (RecCons Age (Expr Int) RecNil))
justAgesOfFamilies = do
  agesOfFamilies <- agesOfFamilies
  project (age << agesOfFamilies!age)

It seems that justAgesOfFamilies should return a single-column query with one row for each family containing their total age, i.e. the result of the query agesOfFamilies without the family column. However, what I get is completely different

*Main> putStrLn $ showSql justAgesOfFamilies 
SELECT SUM(agecol) as age
FROM mytable as T1

This kind of behaviour seems to be an enormous impediment to composability of queries in HaskellDB.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions