git.iko.soy/rowtype-yoga/purescript-yoga-postgres
on add-postgres-koans help sign in
106 lines 2.5 kB history raw
1# PostgreSQL Koans
3Small “will this compile?” puzzles from the typed query builder. Each prompt is short enough to adapt into a post; keep the answer for a follow-up.
5## Koan 1 — GROUP BY
7### Prompt
9PureScript knows both the table schema and selected columns. Should this compile?
11```purescript
12from users
13 # select @"name, email"
14 # groupBy @"name"
15```
17The inferred result row is:
19```purescript
20(name :: String, email :: String)
21```
23PostgreSQL koan: which column betrays us only at runtime?
25### Answer
27It currently compiles and renders:
29```sql
30SELECT name, email FROM users GROUP BY name
31```
33PostgreSQL rejects `email`: every selected, non-aggregated expression must participate in the grouping. The type-level parser validates column existence but does not yet relate the SELECT expressions to GROUP BY.
35## Koan 2 — Nothing to insert
37### Prompt
39Every column has a database-generated value:
41```purescript
42type Config = Table "config"
43 ( id :: Int # PrimaryKey # AutoIncrement
44 , active :: Boolean # Default True
45 , score :: Int # Default 0
46 )
48from (Proxy :: Proxy Config) # insert {}
49```
51The empty record is exactly the right input. What SQL should it produce?
53### Answer
55PostgreSQL expects:
57```sql
58INSERT INTO config DEFAULT VALUES
59```
61The builder currently emits invalid SQL:
63```sql
64INSERT INTO config () VALUES ()
65```
67The input type is correct; the zero-column rendering branch is not.
69## Koan 3 — One means how many?
71### Prompt
73What should `executeSqlOne` return when a query unexpectedly produces two rows?
75```purescript
76executeSqlOne query params connection
77 :: Aff (Either String (Maybe User))
78```
80Choose one:
821. `Left "expected at most one row"`
832. `Right (Just firstRow)`
843. `Right Nothing`
86### Answer
88Today it returns `Right Nothing`. The implementation maps both zero rows and multiple rows to `Nothing`, so “not found” and “cardinality bug” are indistinguishable. A one-row API should preserve that invariant in its result or error channel.
90## Koan 4 — Half a second
92### Prompt
94PostgreSQL returns this `TIME` value:
96```text
9714:30:00.5
98```
100How many milliseconds does the PureScript decoder put in `PGTime`?
102### Answer
104Today: `5`. Correct: `500`.
106The decoder parses the fractional digits directly as milliseconds. PostgreSQL fractions are decimal fractions of a second, so `.5`, `.50`, and `.500` must all decode to 500 milliseconds; longer fractions also need an explicit rounding or truncation rule.