@@ -28,9 +28,9 @@ import qualified Data.ByteString as ByteString
2828import Squeel.PostgreSQL.Schema
2929
3030newtype Expression
31− (params :: [PGType])
32− (tables :: [(Symbol,[(Symbol,PGType)])])
33− (ty :: PGType)
31+ (params :: [NullityType])
32+ (tables :: [(Symbol,[(Symbol,NullityType)])])
33+ (ty :: NullityType)
3434 = UnsafeExpression { renderExpression :: ByteString }
3535
3636class KnownNat n => HasParameter (n :: Nat) params ty | n params -> ty where
@@ -94,7 +94,7 @@ unsafeFunction
9494unsafeFunction fn x = UnsafeExpression $ mconcat
9595 [fn, "(", renderExpression x, ")"]
9696
97−instance PGNum ty => Num (Expression params tables ty) where
97+instance PGNum ty => Num (Expression params tables (nullity ty)) where
9898 (+) = unsafeBinaryOp "+"
9999 (-) = unsafeBinaryOp "-"
100100 (*) = unsafeBinaryOp "*"
@@ -102,7 +102,7 @@ instance PGNum ty => Num (Expression params tables ty) where
102102 signum = unsafeFunction "sign"
103103 fromInteger = UnsafeExpression . fromString . show
104104
105−instance IsString (Expression params tables 'PGText) where
105+instance IsString (Expression params tables (nullity 'PGText)) where
106106 fromString str = UnsafeExpression $
107107 "E\'" <> fromString (escape =<< str) <> "\'"
108108 where
@@ -117,7 +117,7 @@ instance IsString (Expression params tables 'PGText) where
117117 '\\' -> "\\\\"
118118 c -> [c]
119119
120−instance Boolean (Expression params tables 'PGBool) where
120+instance Boolean (Expression params tables ('NotNull 'PGBool)) where
121121 true = UnsafeExpression "TRUE"
122122 false = UnsafeExpression "FALSE"
123123 notB = unsafeUnaryOp "NOT"
@@ -125,10 +125,10 @@ instance Boolean (Expression params tables 'PGBool) where
125125 (||*) = unsafeBinaryOp "OR"
126126
127127type instance BooleanOf (Expression params tables ty) =
128− Expression params tables 'PGBool
128+ Expression params tables ('NotNull 'PGBool)
129129
130130caseWhenThenElse
131− :: [(Expression params tables 'PGBool, Expression params tables ty)]
131+ :: [(Expression params tables ('NotNull 'PGBool), Expression params tables ty)]
132132 -> Expression params tables ty
133133 -> Expression params tables ty
134134caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
@@ -158,9 +158,9 @@ instance OrdB (Expression params tables ty) where
158158 (<=*) = unsafeBinaryOp "<="
159159
160160newtype TableRef
161− (params :: [PGType])
162− (schema :: [(Symbol,[(Symbol,PGType)])])
163− (tables :: [(Symbol,[(Symbol,PGType)])])
161+ (params :: [NullityType])
162+ (schema :: [(Symbol,[(Symbol,NullityType)])])
163+ (tables :: [(Symbol,[(Symbol,NullityType)])])
164164 = UnsafeTableRef { renderTableRef :: ByteString }
165165
166166class KnownSymbol table => HasTable table tables columns
@@ -182,7 +182,7 @@ crossJoin tab tabs = UnsafeTableRef $
182182
183183innerJoin
184184 :: TableRef params schema '[table]
185− -> Expression params (table ': tables) 'PGBool
185+ -> Expression params (table ': tables) ('NotNull 'PGBool)
186186 -> TableRef params schema tables
187187 -> TableRef params schema (table ': tables)
188188innerJoin tab on tabs = UnsafeTableRef $
@@ -192,10 +192,47 @@ innerJoin tab on tabs = UnsafeTableRef $
192192 <> " ON " <>
193193 renderExpression on
194194
195+leftOuterJoin
196+ :: TableRef params schema '[right]
197+ -> Expression params (right ': tables) ('NotNull 'PGBool)
198+ -> TableRef params schema (left : tables)
199+ -> TableRef params schema (NullifyTable right ': left ': tables)
200+leftOuterJoin tab on tabs = UnsafeTableRef $
201+ renderTableRef tabs
202+ <> " LEFT OUTER JOIN " <>
203+ renderTableRef tab
204+ <> " ON " <>
205+ renderExpression on
206+
207+rightOuterJoin
208+ :: TableRef params schema '[right]
209+ -> Expression params (right ': tables) ('NotNull 'PGBool)
210+ -> TableRef params schema (left : tables)
211+ -> TableRef params schema (right ': NullifyTable left ': tables)
212+rightOuterJoin tab on tabs = UnsafeTableRef $
213+ renderTableRef tabs
214+ <> " RIGHT OUTER JOIN " <>
215+ renderTableRef tab
216+ <> " ON " <>
217+ renderExpression on
218+
219+fullOuterJoin
220+ :: TableRef params schema '[right]
221+ -> Expression params (right ': tables) ('NotNull 'PGBool)
222+ -> TableRef params schema (left : tables)
223+ -> TableRef params schema
224+ (NullifyTable right ': NullifyTable left ': tables)
225+fullOuterJoin tab on tabs = UnsafeTableRef $
226+ renderTableRef tabs
227+ <> " FULL OUTER JOIN " <>
228+ renderTableRef tab
229+ <> " ON " <>
230+ renderExpression on
231+
195232data Clauses params tables = Clauses
196− { whereClause :: Maybe (Expression params tables 'PGBool)
197− , limitClause :: Maybe (Expression params '[] 'PGInt8)
198− , offsetClause :: Maybe (Expression params '[] 'PGInt8)
233+ { whereClause :: Maybe (Expression params tables ('NotNull 'PGBool))
234+ , limitClause :: Maybe (Expression params '[] ('NotNull 'PGInt8))
235+ , offsetClause :: Maybe (Expression params '[] ('NotNull 'PGInt8))
199236 }
200237
201238instance Monoid (Clauses params tables) where
@@ -219,9 +256,9 @@ instance Monoid (Clauses params tables) where
219256 }
220257
221258data TableExpression
222− (params :: [PGType])
223− (schema :: [(Symbol,[(Symbol,PGType)])])
224− (tables :: [(Symbol,[(Symbol,PGType)])])
259+ (params :: [NullityType])
260+ (schema :: [(Symbol,[(Symbol,NullityType)])])
261+ (tables :: [(Symbol,[(Symbol,NullityType)])])
225262 = TableExpression
226263 { tableRef :: TableRef params schema tables
227264 , clauses :: Clauses params tables
@@ -249,30 +286,30 @@ instance (HasTable table schema columns, table ~ table')
249286 fromLabel p = TableExpression (getTable p) mempty
250287
251288where_
252− :: Expression params tables 'PGBool
289+ :: Expression params tables ('NotNull 'PGBool)
253290 -> TableExpression params schema tables
254291 -> TableExpression params schema tables
255292where_ wh (TableExpression tabs clauses1) = TableExpression tabs
256293 (clauses1 <> Clauses (Just wh) Nothing Nothing)
257294
258295limit
259− :: Expression params '[] 'PGInt8
296+ :: Expression params '[] ('NotNull 'PGInt8)
260297 -> TableExpression params schema tables
261298 -> TableExpression params schema tables
262299limit lim (TableExpression tabs clauses1) = TableExpression tabs
263300 (clauses1 <> Clauses Nothing (Just lim) Nothing)
264301
265302offset
266− :: Expression params '[] 'PGInt8
303+ :: Expression params '[] ('NotNull 'PGInt8)
267304 -> TableExpression params schema tables
268305 -> TableExpression params schema tables
269306offset off (TableExpression tabs clauses1) = TableExpression tabs
270307 (clauses1 <> Clauses Nothing Nothing (Just off))
271308
272309newtype Selection
273− (params :: [PGType])
274− (schema :: [(Symbol,[(Symbol,PGType)])])
275− (columns :: [(Symbol,PGType)])
310+ (params :: [NullityType])
311+ (schema :: [(Symbol,[(Symbol,NullityType)])])
312+ (columns :: [(Symbol,NullityType)])
276313 = UnsafeSelection
277314 { renderSelection :: ByteString }
278315
@@ -282,12 +319,12 @@ starFrom
282319 -> Selection params schema columns
283320starFrom tabs = UnsafeSelection $ "* FROM " <> renderTabulation tabs
284321
285−tableStarFrom
322+dotStarFrom
286323 :: HasTable table tables columns
287324 => Alias table
288325 -> TableExpression params schema tables
289326 -> Selection params schema columns
290−Alias tab `tableStarFrom` tabs = UnsafeSelection $
327+Alias tab `dotStarFrom` tabs = UnsafeSelection $
291328 fromString (symbolVal' tab) <> ".* FROM" <> renderTabulation tabs
292329
293330from
@@ -303,17 +340,17 @@ list `from` tabs = UnsafeSelection $
303340 . rmap (Const . renderAliased renderExpression)
304341
305342newtype Statement
306− (params :: [PGType])
307− (schema0 :: [(Symbol,[(Symbol,PGType)])])
308− (schema1 :: [(Symbol,[(Symbol,PGType)])])
309− (columns :: [(Symbol,PGType)])
343+ (params :: [NullityType])
344+ (schema0 :: [(Symbol,[(Symbol,NullityType)])])
345+ (schema1 :: [(Symbol,[(Symbol,NullityType)])])
346+ (columns :: [(Symbol,NullityType)])
310347 = UnsafeStatement { renderStatement :: ByteString }
311348
312349newtype PreparedStatement
313− (params :: [PGType])
314− (schema0 :: [(Symbol,[(Symbol,PGType)])])
315− (schema1 :: [(Symbol,[(Symbol,PGType)])])
316− (columns :: [(Symbol,PGType)])
350+ (params :: [NullityType])
351+ (schema0 :: [(Symbol,[(Symbol,NullityType)])])
352+ (schema1 :: [(Symbol,[(Symbol,NullityType)])])
353+ (columns :: [(Symbol,NullityType)])
317354 = UnsafePreparedStatement { renderPreparedStatement :: ByteString }
318355
319356select