on dev help sign in
null_, notNull and values
c08a8a6Eitan Chatav
README.md+1−1
@@ -132,7 +132,7 @@ let
132 createTable #emails
132 createTable #emails
133 ( serial `As` #id :*
133 ( serial `As` #id :*
134 (int & notNull) `As` #user_id :*
134 (int & notNull) `As` #user_id :*
135− (text & null') `As` #email :* Nil )
135+ (text & null_) `As` #email :* Nil )
136 ( primaryKey #id `As` #pk_emails :*
136 ( primaryKey #id `As` #pk_emails :*
137 foreignKey #user_id #users #id
137 foreignKey #user_id #users #id
138 OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
138 OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
squeal-postgresql/exe/Example.hs+1−1
@@ -52,7 +52,7 @@ setup =
52 createTable #emails
52 createTable #emails
53 ( serial `As` #id :*
53 ( serial `As` #id :*
54 (int & notNull) `As` #user_id :*
54 (int & notNull) `As` #user_id :*
55− (text & null') `As` #email :* Nil )
55+ (text & null_) `As` #email :* Nil )
56 ( primaryKey #id `As` #pk_emails :*
56 ( primaryKey #id `As` #pk_emails :*
57 foreignKey #user_id #users #id
57 foreignKey #user_id #users #id
58 OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
58 OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
squeal-postgresql/src/Squeal/PostgreSQL.hs+1−1
@@ -71,7 +71,7 @@
71-- createTable #emails
71-- createTable #emails
72-- ( serial `As` #id :*
72-- ( serial `As` #id :*
73-- (int & notNull) `As` #user_id :*
73-- (int & notNull) `As` #user_id :*
74−-- (text & null') `As` #email :* Nil )
74+-- (text & null_) `As` #email :* Nil )
75-- ( primaryKey #id `As` #pk_emails :*
75-- ( primaryKey #id `As` #pk_emails :*
76-- foreignKey #user_id #users #id
76-- foreignKey #user_id #users #id
77-- OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
77-- OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
squeal-postgresql/src/Squeal/PostgreSQL/Definition.hs+20−21
@@ -69,8 +69,6 @@ module Squeal.PostgreSQL.Definition
69 , createTypeEnumFromHaskell
69 , createTypeEnumFromHaskell
70 , dropType
70 , dropType
71 , ColumnTypeExpression (..)
71 , ColumnTypeExpression (..)
72− , notNull
73− , null'
74 , default_
72 , default_
75 , serial2
73 , serial2
76 , smallserial
74 , smallserial
@@ -122,7 +120,7 @@ CREATE statements
122-- >>> :set -XOverloadedLabels
120-- >>> :set -XOverloadedLabels
123-- >>> :{
121-- >>> :{
124-- renderDefinition $
122-- renderDefinition $
125−-- createTable #tab ((int & null') `As` #a :* (real & null') `As` #b :* Nil) Nil
123+-- createTable #tab ((int & null_) `As` #a :* (real & null_) `As` #b :* Nil) Nil
126-- :}
124-- :}
127-- "CREATE TABLE \"tab\" (\"a\" int NULL, \"b\" real NULL);"
125-- "CREATE TABLE \"tab\" (\"a\" int NULL, \"b\" real NULL);"
128createTable
126createTable
@@ -149,7 +147,7 @@ createTable tab columns constraints = UnsafeDefinition $
149-- >>> type Schema = '["tab" ::: 'Table Table]
147-- >>> type Schema = '["tab" ::: 'Table Table]
150-- >>> :{
148-- >>> :{
151-- renderDefinition
149-- renderDefinition
152−-- (createTableIfNotExists #tab ((int & null') `As` #a :* (real & null') `As` #b :* Nil) Nil :: Definition Schema Schema)
150+-- (createTableIfNotExists #tab ((int & null_) `As` #a :* (real & null_) `As` #b :* Nil) Nil :: Definition Schema Schema)
153-- :}
151-- :}
154-- "CREATE TABLE IF NOT EXISTS \"tab\" (\"a\" int NULL, \"b\" real NULL);"
152-- "CREATE TABLE IF NOT EXISTS \"tab\" (\"a\" int NULL, \"b\" real NULL);"
155createTableIfNotExists
153createTableIfNotExists
@@ -262,8 +260,8 @@ check _cols condition = UnsafeTableConstraintExpression $
262-- let
260-- let
263-- definition :: Definition '[] Schema
261-- definition :: Definition '[] Schema
264-- definition = createTable #tab
262-- definition = createTable #tab
265−-- ( (int & null') `As` #a :*
263+-- ( (int & null_) `As` #a :*
266−-- (int & null') `As` #b :* Nil )
264+-- (int & null_) `As` #b :* Nil )
267-- ( unique (#a :* #b :* Nil) `As` #uq_a_b :* Nil )
265-- ( unique (#a :* #b :* Nil) `As` #uq_a_b :* Nil )
268-- :}
266-- :}
269--
267--
@@ -343,7 +341,7 @@ primaryKey columns = UnsafeTableConstraintExpression $
343-- createTable #emails
341-- createTable #emails
344-- ( serial `As` #id :*
342-- ( serial `As` #id :*
345-- (int & notNull) `As` #user_id :*
343-- (int & notNull) `As` #user_id :*
346−-- (text & null') `As` #email :* Nil )
344+-- (text & null_) `As` #email :* Nil )
347-- ( primaryKey #id `As` #pk_emails :*
345-- ( primaryKey #id `As` #pk_emails :*
348-- foreignKey #user_id #users #id
346-- foreignKey #user_id #users #id
349-- OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
347-- OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
@@ -373,7 +371,7 @@ primaryKey columns = UnsafeTableConstraintExpression $
373-- createTable #employees
371-- createTable #employees
374-- ( serial `As` #id :*
372-- ( serial `As` #id :*
375-- (text & notNull) `As` #name :*
373-- (text & notNull) `As` #name :*
376−-- (integer & null') `As` #employer_id :* Nil )
374+-- (integer & null_) `As` #employer_id :* Nil )
377-- ( primaryKey #id `As` #employees_pk :*
375-- ( primaryKey #id `As` #employees_pk :*
378-- foreignKey #employer_id #employees #id
376-- foreignKey #employer_id #employees #id
379-- OnDeleteCascade OnUpdateCascade `As` #employees_employer_fk :* Nil )
377-- OnDeleteCascade OnUpdateCascade `As` #employees_employer_fk :* Nil )
@@ -575,7 +573,7 @@ class AddColumn ty where
575 -- '["tab" ::: 'Table ('[] :=>
573 -- '["tab" ::: 'Table ('[] :=>
576 -- '[ "col1" ::: 'NoDef :=> 'Null 'PGint4
574 -- '[ "col1" ::: 'NoDef :=> 'Null 'PGint4
577 -- , "col2" ::: 'Def :=> 'Null 'PGtext ])]
575 -- , "col2" ::: 'Def :=> 'Null 'PGtext ])]
578− -- definition = alterTable #tab (addColumn #col2 (text & null' & default_ "foo"))
576+ -- definition = alterTable #tab (addColumn #col2 (text & null_ & default_ "foo"))
579 -- in renderDefinition definition
577 -- in renderDefinition definition
580 -- :}
578 -- :}
581 -- "ALTER TABLE \"tab\" ADD COLUMN \"col2\" text NULL DEFAULT E'foo';"
579 -- "ALTER TABLE \"tab\" ADD COLUMN \"col2\" text NULL DEFAULT E'foo';"
@@ -587,7 +585,7 @@ class AddColumn ty where
587 -- '["tab" ::: 'Table ('[] :=>
585 -- '["tab" ::: 'Table ('[] :=>
588 -- '[ "col1" ::: 'NoDef :=> 'Null 'PGint4
586 -- '[ "col1" ::: 'NoDef :=> 'Null 'PGint4
589 -- , "col2" ::: 'NoDef :=> 'Null 'PGtext ])]
587 -- , "col2" ::: 'NoDef :=> 'Null 'PGtext ])]
590− -- definition = alterTable #tab (addColumn #col2 (text & null'))
588+ -- definition = alterTable #tab (addColumn #col2 (text & null_))
591 -- in renderDefinition definition
589 -- in renderDefinition definition
592 -- :}
590 -- :}
593 -- "ALTER TABLE \"tab\" ADD COLUMN \"col2\" text NULL;"
591 -- "ALTER TABLE \"tab\" ADD COLUMN \"col2\" text NULL;"
@@ -826,17 +824,18 @@ instance (Has alias schema ('Typedef ty))
826 => IsLabel alias (ColumnTypeExpression schema ('NoDef :=> 'NotNull ty)) where
824 => IsLabel alias (ColumnTypeExpression schema ('NoDef :=> 'NotNull ty)) where
827 fromLabel = UnsafeColumnTypeExpression (renderAlias (fromLabel @alias))
825 fromLabel = UnsafeColumnTypeExpression (renderAlias (fromLabel @alias))
828
826
829−null'
827+instance HasNull
830− :: TypeExpression ty
828+ ( TypeExpression ty
831− -> ColumnTypeExpression schema ('NoDef :=> 'Null ty)
829+ -> ColumnTypeExpression schema ('NoDef :=> 'Null ty) ) where
832−null' ty = UnsafeColumnTypeExpression $ renderTypeExpression ty <+> "NULL"
830+ null_ ty = UnsafeColumnTypeExpression $ renderTypeExpression ty <+> "NULL"
833−
831+
832+instance HasNotNull
833+ ( TypeExpression ty
834+ ->
835+ ColumnTypeExpression schema (def :=> 'NotNull ty) ) where
834−-- | used in `createTable` commands as a column constraint to ensure
836+ -- | used in `createTable` commands as a column constraint to ensure
835−-- @NULL@ is not present
837+ -- @NULL@ is not present
836−notNull
837− :: TypeExpression ty
838− -> ColumnTypeExpression schema (def :=> 'NotNull ty)
839−notNull ty = UnsafeColumnTypeExpression $ renderTypeExpression ty <+> "NOT NULL"
838+ notNull ty = UnsafeColumnTypeExpression $ renderTypeExpression ty <+> "NOT NULL"
840
839
841-- | used in `createTable` commands as a column constraint to give a default
840-- | used in `createTable` commands as a column constraint to give a default
842default_
841default_
squeal-postgresql/src/Squeal/PostgreSQL/Expression.hs+28−26
@@ -32,8 +32,8 @@ module Squeal.PostgreSQL.Expression
32 Expression (UnsafeExpression, renderExpression)
32 Expression (UnsafeExpression, renderExpression)
33 , HasParameter (param)
33 , HasParameter (param)
34 -- ** Null
34 -- ** Null
35− , null_
35+ , HasNull (null_)
36− , unNull
36+ , HasNotNull (notNull)
37 , coalesce
37 , coalesce
38 , fromNull
38 , fromNull
39 , isNull
39 , isNull
@@ -221,26 +221,28 @@ instance
221 relation ! column = UnsafeExpression $
221 relation ! column = UnsafeExpression $
222 renderAlias relation <> "." <> renderAlias column
222 renderAlias relation <> "." <> renderAlias column
223
223
224+class HasNull expr where null_ :: expr
225+instance HasNull (Expression rels grouping params ('Null ty)) where
224−-- | analagous to `Nothing`
226+ -- | analagous to `Nothing`
225−--
227+ --
226−-- >>> renderExpression $ null_
228+ -- >>> renderExpression $ null_
227−-- "NULL"
229+ -- "NULL"
230+ null_ = UnsafeExpression "NULL"
231+
232+class HasNotNull expr where notNull :: expr
233+instance HasNotNull
228−null_ :: Expression relations grouping params ('Null ty)
234+ ( Expression rels grouping params ('NotNull ty)
229−null_ = UnsafeExpression "NULL"
235+ ->
230−
236+ Expression rels grouping params ('Null ty) ) where
231−-- | analagous to `Just`
237+ -- | analagous to `Just`
232−--
238+ --
233−-- >>> renderExpression $ unNull true
239+ -- >>> renderExpression $ notNull true
234−-- "TRUE"
240+ -- "TRUE"
235−unNull
236− :: Expression relations grouping params ('NotNull ty)
237− -- ^ not @NULL@
238− -> Expression relations grouping params ('Null ty)
239−unNull = UnsafeExpression . renderExpression
241+ notNull = UnsafeExpression . renderExpression
240
242
241-- | return the leftmost value which is not NULL
243-- | return the leftmost value which is not NULL
242--
244--
243−-- >>> renderExpression $ coalesce [null_, unNull true] false
245+-- >>> renderExpression $ coalesce [null_, notNull true] false
244-- "COALESCE(NULL, TRUE, FALSE)"
246-- "COALESCE(NULL, TRUE, FALSE)"
245coalesce
247coalesce
246 :: [Expression relations grouping params ('Null ty)]
248 :: [Expression relations grouping params ('Null ty)]
@@ -309,7 +311,7 @@ nullIf
309nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
311nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
310 (renderExpression x <> ", " <> renderExpression y)
312 (renderExpression x <> ", " <> renderExpression y)
311
313
312−-- | >>> renderExpression $ array [null_, unNull false, unNull true]
314+-- | >>> renderExpression $ array [null_, notNull false, notNull true]
313-- "ARRAY[NULL, FALSE, TRUE]"
315-- "ARRAY[NULL, FALSE, TRUE]"
314array
316array
315 :: [Expression relations grouping params ('Null ty)]
317 :: [Expression relations grouping params ('Null ty)]
@@ -628,7 +630,7 @@ ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
628-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
630-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
629-- will produce @NULL@s if one of their arguments is @NULL@.
631-- will produce @NULL@s if one of their arguments is @NULL@.
630--
632--
631−-- >>> renderExpression $ unNull true .== null_
633+-- >>> renderExpression $ notNull true .== null_
632-- "(TRUE = NULL)"
634-- "(TRUE = NULL)"
633(.==)
635(.==)
634 :: Expression relations grouping params (nullity ty) -- ^ lhs
636 :: Expression relations grouping params (nullity ty) -- ^ lhs
@@ -637,7 +639,7 @@ ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
637(.==) = unsafeBinaryOp "="
639(.==) = unsafeBinaryOp "="
638infix 4 .==
640infix 4 .==
639
641
640−-- | >>> renderExpression $ unNull true ./= null_
642+-- | >>> renderExpression $ notNull true ./= null_
641-- "(TRUE <> NULL)"
643-- "(TRUE <> NULL)"
642(./=)
644(./=)
643 :: Expression relations grouping params (nullity ty) -- ^ lhs
645 :: Expression relations grouping params (nullity ty) -- ^ lhs
@@ -646,7 +648,7 @@ infix 4 .==
646(./=) = unsafeBinaryOp "<>"
648(./=) = unsafeBinaryOp "<>"
647infix 4 ./=
649infix 4 ./=
648
650
649−-- | >>> renderExpression $ unNull true .>= null_
651+-- | >>> renderExpression $ notNull true .>= null_
650-- "(TRUE >= NULL)"
652-- "(TRUE >= NULL)"
651(.>=)
653(.>=)
652 :: Expression relations grouping params (nullity ty) -- ^ lhs
654 :: Expression relations grouping params (nullity ty) -- ^ lhs
@@ -655,7 +657,7 @@ infix 4 ./=
655(.>=) = unsafeBinaryOp ">="
657(.>=) = unsafeBinaryOp ">="
656infix 4 .>=
658infix 4 .>=
657
659
658−-- | >>> renderExpression $ unNull true .< null_
660+-- | >>> renderExpression $ notNull true .< null_
659-- "(TRUE < NULL)"
661-- "(TRUE < NULL)"
660(.<)
662(.<)
661 :: Expression relations grouping params (nullity ty) -- ^ lhs
663 :: Expression relations grouping params (nullity ty) -- ^ lhs
@@ -664,7 +666,7 @@ infix 4 .>=
664(.<) = unsafeBinaryOp "<"
666(.<) = unsafeBinaryOp "<"
665infix 4 .<
667infix 4 .<
666
668
667−-- | >>> renderExpression $ unNull true .<= null_
669+-- | >>> renderExpression $ notNull true .<= null_
668-- "(TRUE <= NULL)"
670-- "(TRUE <= NULL)"
669(.<=)
671(.<=)
670 :: Expression relations grouping params (nullity ty) -- ^ lhs
672 :: Expression relations grouping params (nullity ty) -- ^ lhs
@@ -673,7 +675,7 @@ infix 4 .<
673(.<=) = unsafeBinaryOp "<="
675(.<=) = unsafeBinaryOp "<="
674infix 4 .<=
676infix 4 .<=
675
677
676−-- | >>> renderExpression $ unNull true .> null_
678+-- | >>> renderExpression $ notNull true .> null_
677-- "(TRUE > NULL)"
679-- "(TRUE > NULL)"
678(.>)
680(.>)
679 :: Expression relations grouping params (nullity ty) -- ^ lhs
681 :: Expression relations grouping params (nullity ty) -- ^ lhs
squeal-postgresql/src/Squeal/PostgreSQL/Migration.hs+1−1
@@ -53,7 +53,7 @@ let
53 createTable #emails
53 createTable #emails
54 ( serial `As` #id :*
54 ( serial `As` #id :*
55 (int & notNull) `As` #user_id :*
55 (int & notNull) `As` #user_id :*
56− (text & null') `As` #email :* Nil )
56+ (text & null_) `As` #email :* Nil )
57 ( primaryKey #id `As` #pk_emails :*
57 ( primaryKey #id `As` #pk_emails :*
58 foreignKey #user_id #users #id
58 foreignKey #user_id #users #id
59 OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
59 OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )
squeal-postgresql/src/Squeal/PostgreSQL/Query.hs+20
@@ -35,6 +35,7 @@ module Squeal.PostgreSQL.Query
35 , selectDistinctStar
35 , selectDistinctStar
36 , selectDotStar
36 , selectDotStar
37 , selectDistinctDotStar
37 , selectDistinctDotStar
38+ , values
38 -- * Table Expressions
39 -- * Table Expressions
39 , TableExpression (..)
40 , TableExpression (..)
40 , renderTableExpression
41 , renderTableExpression
@@ -424,6 +425,25 @@ selectDistinctDotStar rel relations = UnsafeQuery $
424 "SELECT DISTINCT" <+> renderAlias rel <> ".*"
425 "SELECT DISTINCT" <+> renderAlias rel <> ".*"
425 <+> renderTableExpression relations
426 <+> renderTableExpression relations
426
427
428+values
429+ :: SListI cols
430+ => NP (Aliased (Expression '[] 'Ungrouped params)) cols
431+ -> [NP (Aliased (Expression '[] 'Ungrouped params)) cols]
432+ -> Query schema params cols
433+values rw rws = UnsafeQuery $ "SELECT * FROM"
434+ <+> parenthesized (
435+ "VALUES"
436+ <+> commaSeparated
437+ ( parenthesized
438+ . renderCommaSeparated renderValuePart <$> rw:rws )
439+ ) <+> "AS t"
440+ <+> parenthesized (renderCommaSeparated renderAliasPart rw)
441+ where
442+ renderAliasPart, renderValuePart
443+ :: Aliased (Expression '[] 'Ungrouped params) ty -> ByteString
444+ renderAliasPart (_ `As` name) = renderAlias name
445+ renderValuePart (value `As` _) = renderExpression value
446+
427{-----------------------------------------
447{-----------------------------------------
428Table Expressions
448Table Expressions
429-----------------------------------------}
449-----------------------------------------}