valderman / selda

A type-safe, high-level SQL library for Haskell
https://selda.link
MIT License
478 stars 58 forks source link

Invalid queries generated for PSQL when using two `distinct` clauses #165

Closed TomMD closed 3 years ago

TomMD commented 3 years ago

The error:

SqlError "error executing query `SELECT \"tmp_2\" FROM (SELECT COUNT(\"name_0\") AS \"tmp_2\" FROM (SELECT DISTINCT 1 FROM (SELECT 1 FROM \"people\") AS q0) AS q1) AS q2': ERROR:  column \"name_0\" does not exist\nLINE 1: SELECT \"tmp_2\" FROM (SELECT COUNT(\"name_0\") AS \"tmp_2\" FROM ...\n                                          ^\n"

And server side we see:

2021-01-27 20:08:52.485 UTC [55] ERROR:  column "name_0" does not exist at character 35
2021-01-27 20:08:52.485 UTC [55] STATEMENT:  SELECT "tmp_2" FROM (SELECT COUNT("name_0") AS "tmp_2" FROM (SELECT DISTINCT 1 FROM (SELECT 1 FROM "people") AS q0) AS q1) AS q2

Is generated from:

#!/usr/bin/env cabal
{- cabal:
    build-depends: base, selda, selda-postgresql
-}
{-# LANGUAGE DeriveGeneric, OverloadedStrings, OverloadedLabels #-}
import Database.Selda
import Database.Selda.PostgreSQL

data Person = Person
  { name :: Text
  } deriving Generic
instance SqlRow Person

people :: Table Person
people = table "people" [#name :- primary]

borked :: Query s (Col s Int)
borked = aggregate $ do
    x <- distinct $ do
            t <- select people
            pure (t ! #name)
    _ <- distinct $ do
            t <- select people
            pure (t ! #name)
    pure (count x)

info = PGConnectInfo
  { pgHost = "127.0.0.1"
  , pgPort = 5432
  , pgDatabase = "postgres"
  , pgSchema   = Nothing
  , pgUsername = Just "postgres"
  , pgPassword = Just "password"
  }

main = withPostgreSQL info $ do
  createTable people
  _ <- insertWithPK people [ Person "Main" ]
  _ <- insertWithPK people [ Person "Elizabeth" ]

  nr <- query borked
  liftIO $ print nr

N.B. this works with sqlite.

TomMD commented 3 years ago

This one is non-trivial for me to debug. Is there an active maintainer with spare time who can jump in or give some suggestions?