[1      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                        ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                     Rendering helper functions(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone,DFQVh*Parenthesize a .Concatenate two s with a space between.Comma separate a list of s.6Comma separate the renderings of a heterogeneous list.Comma separate the / renderings of a heterogeneous list, dropping s.Render a promoted .-Embedding of PostgreSQL type and alias system(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&'+,-0168;<=>?ADFQSTVhS Drop all Ls that involve a column Check if a L involves a columnA  constraint proves that a   I of a record type has the same field names as the column AliasesOf of a Q. A  , constraint is an equality constraint on a   and the column alias in a V pair.!Rename alias0 alias1 xs replaces the alias alias0 by alias1 in xs and is used in  and ."Alter alias xs x& replaces the type associated with an alias in xs with the type x and is used in  and .# Drop alias xs" removes the type associated with alias in xs and is used in  statements and in  ALTER TABLE  statements.$Create alias x xs adds  alias ::: x to the end of xs and is used in  statements and in  ALTER TABLE .%% is simply promoted  and is used in JOINs in s.&&# is an idempotent that nullifies a DE used to nullify the left or right hand side of an outer join in a .''# is an idempotent that nullifies a Q.((# is an idempotent that nullifies a R.)) is a constraint that proves a Q has some NOT NULL.** is a constraint that proves a Q has no NULLs.++! is a constraint that proves two Q%s have the same length and the same Rs.,, forgets about NULL and any column constraints.-- is a constraint on ] whose s have  and  functions... is a constraint on ] whose s have  and  constraints.// is a constraint on ] whose  s have a  constraint.0In x xs" is a constraint that proves that x is in xs.1Elem is a promoted .2 Analagous to , the constraint 2 defines 30 for a column alias qualified by a table alias.4Has alias fields field# is a constraint that proves that fields has a field of alias ::: field.5HasUnique alias fields field# is a constraint that proves that fields is a singleton of alias ::: field.66 retains the AliasesOf in a row.7The 8) operator is used to name an expression. 8 is like a demoted version of V.8Just "hello" `As` #hi :: Aliased Maybe ("hi" ::: String)As (Just "hello") Alias99*es are proxies for a type level string or  and have an  instance so that with -XOverloadedLabels:set -XOverloadedLabels#foobar :: Alias "foobar"Alias;A ;f constraint indicates that a table qualified column is a member of the auxiliary namespace created by GROUP BY. clauses and thus, may be called in an output  without aggregating.<<( is an auxiliary namespace, created by GROUP BY clauses (%), and used for typesafe aggregation=no aggregation permitted>8aggregation required for any column which is not grouped??0 adds both trivial table and column constraints.@@+ removes both table and column constraints.AA removes table constraints.BB adds `U column constraints.CC removes column constraints.DD is a row of Fs, thought of as a product.EA monokinded empty F.FF is a row of X:{0type family PersonRelation :: RelationType where PersonRelation =) '[ "name" ::: 'NotNull 'PGtext) , "age" ::: 'NotNull 'PGint4) , "dateOfBirth" ::: 'Null 'PGdate ]:}GA monokinded empty H.HH is a row of Is, thought of as a union.:{&type family Schema :: TablesType where Schema = '[ "users" :::4 '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>. '[ "id" ::: 'Def :=> 'NotNull 'PGint42 , "name" ::: 'NoDef :=> 'NotNull 'PGtext? , "vec" ::: 'NoDef :=> 'NotNull ('PGvararray 'PGint2) ] , "emails" :::0 '[ "pk_emails" ::: 'PrimaryKey '["id"]E , "fk_user_id" ::: 'ForeignKey '["user_id"] "users" '["id"] ] :=>. '[ "id" ::: 'Def :=> 'NotNull 'PGint45 , "user_id" ::: 'NoDef :=> 'NotNull 'PGint40 , "email" ::: 'NoDef :=> 'Null 'PGtext ] ]:}IIN encodes a row of constraints on a table as well as the types of its columns.:{)type family UsersTable :: TableType where UsersTable =/ '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>1 '[ "id" ::: 'Def :=> 'NotNull 'PGint41 , "name" ::: 'NoDef :=> 'NotNull 'PGtext ]:}JA monokinded empty K.KA K is a row of Ls.LLD encodes various forms of data constraints of columns in a table. Ls give you as much control over the data in your tables as you wish. If a user attempts to store data in a column that would violate a constraint, an error is raised. This applies even if the value came from the default value definition.QQ is a row of Rs.:{-type family UsersColumns :: ColumnsType where UsersColumns =- '[ "name" ::: 'NoDef :=> 'NotNull 'PGtext- , "id" ::: 'Def :=> 'NotNull 'PGint4 ]:}RR encodes the allowance of DEFAULT and NULL and the base ] for a column. :set -XTypeFamilies -XTypeInTypeimport GHC.TypeLitsMtype family IdColumn :: ColumnType where IdColumn = 'Def :=> 'NotNull 'PGint4Rtype family EmailColumn :: ColumnType where EmailColumn = 'NoDef :=> 'Null 'PGtextSS encodes the availability of DEFAULTM for inserts and updates. A column can be assigned a default value. A data | command can also request explicitly that a column be set to its default value, without having to know what that value is.TDEFAULT% is available for inserts and updatesUDEFAULT' is unavailable for inserts and updatesVThe alias operator V is like a promoted version of 8W, a type level pair between an alias and some type, like a column alias and either a R or X or a table alias and either a I or a F or a constraint alias and a L.WThe constraint operator, WS is a type level pair between a "constraint" and some type, for use in pairing a S with a X to produce a R or a K and a Q to produce a I.XX: encodes the potential presence or definite absence of a NULLB allowing operations which are sensitive to such to be well typed.:kind 'Null 'PGint4'Null 'PGint4 :: NullityType:kind 'NotNull ('PGvarchar 50)''NotNull ('PGvarchar 50) :: NullityTypeYNULL may be presentZNULL is absent[The object identifier of a ].:set -XTypeApplications oid @'PGbool16]]. is the promoted datakind of PostgreSQL types.import Squeal.PostgreSQL.Schema :kind 'PGbool'PGbool :: PGType^logical Boolean (true/false)_signed two-byte integer`signed four-byte integerasigned eight-byte integerb arbitrary precision numeric typec0single precision floating-point number (4 bytes)d0double precision floating-point number (8 bytes)efixed-length character stringf variable-length character stringg variable-length character stringhbinary data ("byte array")idate and time (no time zone)j"date and time, including time zonek calendar date (year, month, day)ltime of day (no time zone)m time of day, including time zonen time spanouniversally unique identifierpIPv4 or IPv6 host addressqtextual JSON datarbinary JSON data, decomposedsvariable length arraytfixed length arrayu0an escape hatch for unsupported PostgreSQL typesvrenderAlias #jimbob"jimbob"w=let renderMaybe = fromString . maybe "Nothing" (const "Just")8renderAliasedAs renderMaybe (Just (3::Int) `As` #an_int)"Just AS an_int"] !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLNMOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvw]]^_`abcdefghijklmnopqrstu[\XYZRQFEDIHG<=>;WSTULMNOPKJV9:v78w64523%$#"!10/-.,+*)('&CBA@?  23789:<=>LMNOPSTUXYZ[\]^_`abcdefghijklmnopqrstu39 V6W7Squeal expressions(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&',-016;<=>?ADFKQSTV]hQtn is a demoted version of a ]s are used in s and  createTable commands.A J from a table expression is a way to call a table reference by its alias.A constraint for ]3s that you can take averages of and the resulting ].A  is a boolean valued '. While SQL allows conditions to have NULL%, Squeal instead chooses to disallow NULL%, forcing one to handle the case of NULL explicitly to produce a .A X constraint is used to indicate a value that is supplied externally to a SQL statement.  , ! and "V support specifying data values separately from the SQL command string, in which case 3s are used to refer to the out-of-line data values.Gs are used in a variety of contexts, such as in the target list of the select" command, as new column values in  insertInto or update, or in search s in a number of commands.The expression syntax allows the calculation of values from primitive expression using arithmetic, logical, and other operations. analagous to renderExpression $ null_"NULL" analagous to renderExpression $ unNull true"TRUE"+return the leftmost value which is not NULL6renderExpression $ coalesce [null_, unNull true] false"COALESCE(NULL, TRUE, FALSE)" analagous to #$ using COALESCE&renderExpression $ fromNull true null_"COALESCE(NULL, TRUE)"!renderExpression $ null_ & isNull"NULL IS NULL"$renderExpression $ null_ & isn'tNull"NULL IS NOT NULL" analagous to  using IS NULL,renderExpression $ matchNull true not_ null_6"CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END"right inverse to #, if its arguments are equal then  gives NULL.#:set -XTypeApplications -XDataKindsGrenderExpression @_ @_ @'[_] $ fromNull false (nullIf false (param @1))0"COALESCE(NULL IF (FALSE, ($1 :: bool)), FALSE)";renderExpression $ array [null_, unNull false, unNull true]"ARRAY[NULL, FALSE, TRUE]"CrenderExpression @_ @_ @'[_] $ greatest currentTimestamp [param @1]?"GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))"1renderExpression $ least currentTimestamp [null_] "LEAST(CURRENT_TIMESTAMP, NULL)"1renderExpression $ unsafeBinaryOp "OR" true false"(TRUE OR FALSE)"+renderExpression $ unsafeUnaryOp "NOT" true "(NOT TRUE)"*renderExpression $ unsafeFunction "f" true "f(TRUE)":{letH expression :: Expression relations grouping params (nullity 'PGfloat4) expression = atan2_ pi 2in renderExpression expression:}"atan2(pi(), 2)"#renderExpression $ true & cast int4"(TRUE :: int4)"&integer division, truncates the result:{letF expression :: Expression relations grouping params (nullity 'PGint2) expression = 5 `quot_` 2in renderExpression expression:} "(5 / 2)"remainder upon integer division:{letF expression :: Expression relations grouping params (nullity 'PGint2) expression = 5 `rem_` 2in renderExpression expression:} "(5 % 2)":{letH expression :: Expression relations grouping params (nullity 'PGfloat4) expression = trunc piin renderExpression expression:} "trunc(pi())":{letH expression :: Expression relations grouping params (nullity 'PGfloat4) expression = round_ piin renderExpression expression:} "round(pi())":{letH expression :: Expression relations grouping params (nullity 'PGfloat4) expression = ceiling_ piin renderExpression expression:}"ceiling(pi())"renderExpression true"TRUE"renderExpression false"FALSE"renderExpression $ not_ true "(NOT TRUE)"!renderExpression $ true .&& false"(TRUE AND FALSE)"!renderExpression $ true .|| false"(TRUE OR FALSE)":{letF expression :: Expression relations grouping params (nullity 'PGint2)9 expression = caseWhenThenElse [(true, 1), (false, 2)] 3in renderExpression expression:}4"CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END":{letF expression :: Expression relations grouping params (nullity 'PGint2)" expression = ifThenElse true 1 0in renderExpression expression:}""CASE WHEN TRUE THEN 1 ELSE 0 END"Comparison operations like , , , ,  and  will produce NULLs if one of their arguments is NULL.(renderExpression $ unNull true .== null_"(TRUE = NULL)"(renderExpression $ unNull true ./= null_"(TRUE <> NULL)"(renderExpression $ unNull true .>= null_"(TRUE >= NULL)"'renderExpression $ unNull true .< null_"(TRUE < NULL)"(renderExpression $ unNull true .<= null_"(TRUE <= NULL)"'renderExpression $ unNull true .> null_"(TRUE > NULL)"renderExpression currentDate"CURRENT_DATE"renderExpression currentTime"CURRENT_TIME"!renderExpression currentTimestamp"CURRENT_TIMESTAMP"renderExpression localTime "LOCALTIME"renderExpression localTimestamp"LOCALTIMESTAMP""renderExpression $ lower "ARRRGGG""lower(E'ARRRGGG')"renderExpression $ upper "eeee""upper(E'eeee')"$renderExpression $ charLength "four""char_length(E'four')"The  expression returns true if the string matches the supplied pattern. If patterns does not contain percent signs or underscores, then the pattern only represents the string itself; in that case  acts like the equals operator. An underscore (_) in pattern stands for (matches) any single character; a percent sign (%) matches any sequence of zero or more characters.$renderExpression $ "abc" `like` "a%""(E'abc' LIKE E'a%')"*escape hatch to define aggregate functions?escape hatch to define aggregate functions over distinct values:{letl expression :: Expression '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Grouped bys) params ('Null 'PGnumeric) expression = sum_ #colin renderExpression expression:} "sum(col)":{letp expression :: Expression '[tab ::: '["col" ::: nullity 'PGnumeric]] ('Grouped bys) params (nullity 'PGnumeric) expression = sumDistinct #colin renderExpression expression:}"sum(DISTINCT col)":{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4) expression = bitAnd #colin renderExpression expression:}"bit_and(col)":{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4) expression = bitOr #colin renderExpression expression:} "bit_or(col)":{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)" expression = bitAndDistinct #colin renderExpression expression:}"bit_and(DISTINCT col)":{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)! expression = bitOrDistinct #colin renderExpression expression:}"bit_or(DISTINCT col)":{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool) expression = boolAnd #colin renderExpression expression:}"bool_and(col)":{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool) expression = boolOr #colin renderExpression expression:}"bool_or(col)":{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)# expression = boolAndDistinct #colin renderExpression expression:}"bool_and(DISTINCT col)":{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)" expression = boolOrDistinct #colin renderExpression expression:}"bool_or(DISTINCT col)"4A special aggregation that does not require an inputrenderExpression countStar "count(*)":{lete expression :: Expression '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8) expression = count #colin renderExpression expression:} "count(col)":{lete expression :: Expression '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)! expression = countDistinct #colin renderExpression expression:}"count(DISTINCT col)" synonym for :{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool) expression = every #colin renderExpression expression:} "every(col)" synonym for :{leti expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)! expression = everyDistinct #colin renderExpression expression:}"every(DISTINCT col)"minimum and maximum aggregationminimum and maximum aggregationminimum and maximum aggregationminimum and maximum aggregationlogical Boolean (true/false)signed two-byte integersigned two-byte integersigned four-byte integersigned four-byte integersigned four-byte integersigned eight-byte integersigned eight-byte integer arbitrary precision numeric type0single precision floating-point number (4 bytes)0single precision floating-point number (4 bytes)0double precision floating-point number (8 bytes)0double precision floating-point number (8 bytes)hnot a true type, but merely a notational convenience for creating unique identifier columns with type `_hnot a true type, but merely a notational convenience for creating unique identifier columns with type `_hnot a true type, but merely a notational convenience for creating unique identifier columns with type ``hnot a true type, but merely a notational convenience for creating unique identifier columns with type ``hnot a true type, but merely a notational convenience for creating unique identifier columns with type `ahnot a true type, but merely a notational convenience for creating unique identifier columns with type `a variable-length character stringfixed-length character stringfixed-length character string variable-length character string variable-length character stringbinary data ("byte array")date and time (no time zone)"date and time, including time zone calendar date (year, month, day) time of day (no time zone)  time of day, including time zone  time span universally unique identifier IPv4 or IPv6 host addresstextual JSON databinary JSON data, decomposedvariable length arrayfixed length array/renderTypeExpression (fixarray (Proxy @2) json) "json[2]"used in  createTable, commands as a column constraint to ensure NULL is not presentused in  createTable2 commands as a column constraint to give a default6what to averagewhat to averagenot NULLNULLs may be presentNULL is absentwhat to convert NULL to possibly NULL possibly NULLwhat to convert NULL tofunction to perform when NULL is absentNULL is absentNULL is absentarray elementsneeds at least 1 argumentor moreneeds at least 1 argumentor moreoperatoroperatorfunction numerator denominatortype to cast asvalue to convert numerator denominator numerator denominatorfractional numberfractional numberfractional numberwhens and thenselsethenelselhsrhslhsrhslhsrhslhsrhslhsrhslhsrhsstring to lower casestring to upper casestring to measurestringpatternaggregate functionaggregate function what to sum what to sumwhat to aggregatewhat to aggregatewhat to aggregatewhat to aggregatewhat to aggregatewhat to aggregatewhat to aggregatewhat to aggregate what to count what to countwhat to aggregatewhat to aggregatewhat to aggregatewhat to aggregatewhat to aggregatewhat to aggregate|     |     444444Squeal queries(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&',-016;<=>?FKSTV]h"-MMs are used by sortBy& to optionally sort the results of a i. N or O set the sort direction of a Z result column to ascending or descending. Ascending order puts smaller values first, where "smaller" is defined in terms of the ? operator. Similarly, descending order is determined with the  operator. P, Q, R and Sp options are used to determine whether nulls appear before or after non-null values in the sort ordering of a Y result column.TA T; is used to eliminate groups that are not of interest. An = ` may only use U while a > ` must use V% whose conditions are combined with .WA W indicates the < of a `. A X indicates = while a Y indicates >. NoGroups is distinguised from  Group Nil& since no aggregation can be done on NoGroups while all output s must be aggregated in  Group Nil. In general, all output s in the complement of bys must be aggregated in  Group bys.ZZs are used in { to reference a list of columns which are then used to group together those rows in a table that have the same values in all the columns listed. By #col' will reference an unambiguous column col ; otherwise By2 (#tab ! #col)* will reference a table qualified column tab.col.]A ]? can be a table name, or a derived table such as a subquery, a JOIN- construct, or complex combinations of these.`A `4 computes a table. The table expression contains a b" that is optionally followed by a c, d, e, f, g and hs. Trivial table expressions simply refer to a table on disk, a so-called base table, but more complex expressions can be used to modify or combine base tables in various ways.bVA table reference that can be a table name, or a derived table such as a subquery, a JOIN- construct, or complex combinations of these.c)optional search coditions, combined with . After the processing of the b! is done, each row of the derived virtual table is checked against the search condition. If the result of the condition is true, the row is kept in the output table, otherwise it is discarded. The search condition typically references at least one column of the table generated in the bP; this is not required, but otherwise the WHERE clause will be fairly useless.dThe d is used to group together those rows in a table that have the same values in all the columns listed. The order in which the columns are listed does not matter. The effect is to combine each set of rows having common values into one group row that represents all rows in the group. This is done to eliminate redundancy in the output and/or compute aggregates that apply to these groups.e"If a table has been grouped using groupBy0, but only certain groups are of interest, the e can be used, much like a c;, to eliminate groups from the result. Expressions in the ew can refer both to grouped expressions and to ungrouped expressions (which necessarily involve an aggregate function).fThe f. is for optional sorting. When more than one Mu is specified, the later (right) values are used to sort rows that are equal according to the earlier (left) values.gThe g is combined with  to give a limit count if nonempty. If a limit count is given, no more than that many rows will be returned (but possibly fewer, if the query itself yields fewer rows).hThe h is combined with  to give an offset count if nonempty. The offset count says to skip that many rows before beginning to return rows. The rows are skipped before the limit count is applied.iVThe process of retrieving or the command to retrieve data from a database is called a i. The r, t, v, s, u and w& commands are used to specify queries. simple query::{ let query :: Query> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]] '[] '["col" ::: 'Null 'PGint4]2 query = selectStar (from (table (#tab `As` #t)))in renderQuery query:}"SELECT * FROM tab AS t"restricted query::{let query :: Query '[ "tab" ::: '[] :=>0 '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint43 , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ]] '[]! '[ "sum" ::: 'NotNull 'PGint4$ , "col1" ::: 'NotNull 'PGint4 ] query = select< ((#col1 + #col2) `As` #sum :* #col1 `As` #col1 :* Nil)# ( from (table (#tab `As` #t))! & where_ (#col1 .> #col2) & where_ (#col2 .> 0) )in renderQuery query:}^"SELECT (col1 + col2) AS sum, col1 AS col1 FROM tab AS t WHERE ((col1 > col2) AND (col2 > 0))" subquery::{ let query :: Query> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]] '[] '["col" ::: 'Null 'PGint4] query = selectStarL (from (subquery (selectStar (from (table (#tab `As` #t))) `As` #sub)))in renderQuery query:}/"SELECT * FROM (SELECT * FROM tab AS t) AS sub"limits and offsets::{ let query :: Query> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]] '[] '["col" ::: 'Null 'PGint4] query = selectStarN (from (table (#tab `As` #t)) & limit 100 & offset 2 & limit 50 & offset 2)in renderQuery query:}*"SELECT * FROM tab AS t LIMIT 50 OFFSET 4"parameterized query::{ let query :: QueryC '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGfloat8]] '[ 'NotNull 'PGfloat8]# '["col" ::: 'NotNull 'PGfloat8] query = selectStar= (from (table (#tab `As` #t)) & where_ (#col .> param @1))in renderQuery query:}5"SELECT * FROM tab AS t WHERE (col > ($1 :: float8))"aggregation query::{let query :: Query '[ "tab" ::: '[] :=>0 '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint43 , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ]] '[]! '[ "sum" ::: 'NotNull 'PGint4$ , "col1" ::: 'NotNull 'PGint4 ] query =< select (sum_ #col2 `As` #sum :* #col1 `As` #col1 :* Nil)& ( from (table (#tab `As` #table1)) & group (By #col1 :* Nil) * & having (#col1 + sum_ #col2 .> 1) )in renderQuery query:}h"SELECT sum(col2) AS sum, col1 AS col1 FROM tab AS table1 GROUP BY col1 HAVING ((col1 + sum(col2)) > 1)" sorted query::{ let query :: Query> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]] '[] '["col" ::: 'Null 'PGint4] query = selectStarB (from (table (#tab `As` #t)) & orderBy [#col & AscNullsFirst])in renderQuery query:}5"SELECT * FROM tab AS t ORDER BY col ASC NULLS FIRST"joins::set -XFlexibleContexts:{'let query :: Query '[ "orders" :::- '["pk_orders" ::: PrimaryKey '["id"]M ,"fk_customers" ::: ForeignKey '["customer_id"] "customers" '["id"]O ,"fk_shippers" ::: ForeignKey '["shipper_id"] "shippers" '["id"]] :=>3 '[ "id" ::: 'NoDef :=> 'NotNull 'PGint47 , "price" ::: 'NoDef :=> 'NotNull 'PGfloat49 , "customer_id" ::: 'NoDef :=> 'NotNull 'PGint49 , "shipper_id" ::: 'NoDef :=> 'NotNull 'PGint4 ] , "customers" :::5 '["pk_customers" ::: PrimaryKey '["id"]] :=>0 '[ "id" ::: 'NoDef :=> 'NotNull 'PGint42 , "name" ::: 'NoDef :=> 'NotNull 'PGtext ] , "shippers" :::4 '["pk_shippers" ::: PrimaryKey '["id"]] :=>0 '[ "id" ::: 'NoDef :=> 'NotNull 'PGint42 , "name" ::: 'NoDef :=> 'NotNull 'PGtext ] ] '[]+ '[ "order_price" ::: 'NotNull 'PGfloat4+ , "customer_name" ::: 'NotNull 'PGtext* , "shipper_name" ::: 'NotNull 'PGtext ] query = select& ( #o ! #price `As` #order_price :*' #c ! #name `As` #customer_name :*, #s ! #name `As` #shipper_name :* Nil )# ( from (table (#orders `As` #o). & innerJoin (table (#customers `As` #c))( (#o ! #customer_id .== #c ! #id)- & innerJoin (table (#shippers `As` #s))* (#o ! #shipper_id .== #s ! #id)) )in renderQuery query:}"SELECT o.price AS order_price, c.name AS customer_name, s.name AS shipper_name FROM orders AS o INNER JOIN customers AS c ON (o.customer_id = c.id) INNER JOIN shippers AS s ON (o.shipper_id = s.id)" self-join::{ let query :: Query> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]] '[] '["col" ::: 'Null 'PGint4] query = selectDotStar #t1F (from (table (#tab `As` #t1) & crossJoin (table (#tab `As` #t2))))in renderQuery query:}1"SELECT t1.* FROM tab AS t1 CROSS JOIN tab AS t2"set operations::{ let query :: Query> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]] '[] '["col" ::: 'Null 'PGint4] query =, selectStar (from (table (#tab `As` #t))) `unionAll`, selectStar (from (table (#tab `As` #t)))in renderQuery query:}="(SELECT * FROM tab AS t) UNION ALL (SELECT * FROM tab AS t)"lDThe results of two queries can be combined using the set operation l!. Duplicate rows are eliminated. mDThe results of two queries can be combined using the set operation m2, the disjoint union. Duplicate rows are retained.nDThe results of two queries can be combined using the set operation n2, the intersection. Duplicate rows are eliminated.oDThe results of two queries can be combined using the set operation o0, the intersection. Duplicate rows are retained.pDThe results of two queries can be combined using the set operation p4, the set difference. Duplicate rows are eliminated.qDThe results of two queries can be combined using the set operation q2, the set difference. Duplicate rows are retained.rthe ` in the r command constructs an intermediate virtual table by possibly combining tables, views, eliminating rows, grouping, etc. This table is finally passed on to processing by the select list. The select list determines which columns of the intermediate table are actually output.svAfter the select list has been processed, the result table can be subject to the elimination of duplicate rows using s.tThe simplest kind of query is t= which emits all columns that the table expression produces.uA uU emits all columns that the table expression produces and eliminates duplicate rows.vrWhen working with multiple tables, it can also be useful to ask for all the columns of a particular table, using v.wA wQ asks for all the columns of a particular table, and eliminates duplicate rows.x Render a `yA y generates a ` from a table reference that can be a table name, or a derived table such as a subquery, a JOIN construct, or complex combinations of these. A y may be transformed by z, {, |, }, ~ and  , using the K operator to match the left-to-right sequencing of their placement in SQL.zA z is an endomorphism of `(s which adds a search condition to the c.{A { is a transformation of `s which switches its < from = to >. Use  group Nil/ to perform a "grand total" aggregation query.|A | is an endomorphism of `(s which adds a search condition to the e.}An } is an endomorphism of `1s which appends an ordering to the right of the f.~A ~ is an endomorphism of `s which adds to the g.An  is an endomorphism of `s which adds to the h.A real  is a table from the schema. derives a table from a i.left & crossJoin right2. For every possible combination of rows from left and rightc (i.e., a Cartesian product), the joined table will contain a row consisting of all columns in left followed by all columns in right. If the tables have n and m3 rows respectively, the joined table will have n * m rows.left & innerJoin right on&. The joined table is filtered by the on condition.left & leftOuterJoin right on?. First, an inner join is performed. Then, for each row in left that does not satisfy the on condition with any row in right7, a joined row is added with null values in columns of rightI. Thus, the joined table always has at least one row for each row in left.left & rightOuterJoin right on?. First, an inner join is performed. Then, for each row in right that does not satisfy the on condition with any row in left7, a joined row is added with null values in columns of leftg. This is the converse of a left join: the result table will always have a row for each row in right.left & fullOuterJoin right on?. First, an inner join is performed. Then, for each row in left that does not satisfy the on condition with any row in right7, a joined row is added with null values in columns of right. Also, for each row of right> that does not satisfy the join condition with any row in left2, a joined row with null values in the columns of left is added. Renders a Z. Renders a W. Render a T. Render a M.r select listintermediate virtual tables select listintermediate virtual tabletintermediate virtual tableuintermediate virtual tablevparticular virtual subtableintermediate virtual tablewparticular virtual tableintermediate virtual tableytable referencezfiltering condition{grouped columns|having condition}sort expressions~limit parameteroffset parameterrightleftrighton conditionleftrighton conditionleftrighton conditionleftrighton conditionleft>MNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~>ijklmnopqrstuvw`abcdefghxyz{|}~]^_Z[\WXYTUVMNOPQRSMNOPQRSTUVWXYZ[\]^_`abcdefghijk!Squeal data manipulation language(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&',-016<FKQSTV]|A > specifies an action to perform upon a constraint violation.  will raise an error. ! simply avoids inserting a row. N updates the existing row that conflicts with the row proposed for insertion.A  computes and return value(s) based on each row actually inserted, updated or deleted. This is primarily useful for obtaining values that were supplied by defaults, such as a serial sequence number. However, any expression using the table's columns is allowed. Only rows that were successfully inserted or updated or deleted will be returned. For example, if a row was locked but not updated because an = condition was not satisfied, the row will not be returned. * will return all columns in the row. Use  Returning Nil8 in the common case where no return values are desired.+s are values to insert or update in a row  updates with the same value.  inserts or updates with the DEFAULT value  a value to be an E, relative to the given row for an update, and closed for an insert.A  is a statement which may modify data in the database, but does not alter the schema. Examples are inserts, updates and deletes. A i is also considered a % even though it does not modify data.simple insert::{ let manipulation :: Manipulation '[ "tab" ::: '[] :=>/ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint48 , "col2" ::: 'Def :=> 'NotNull 'PGint4 ]] '[] '[] manipulation =C insertRow_ #tab (Set 2 `As` #col1 :* Default `As` #col2 :* Nil)"in renderManipulation manipulation:}3"INSERT INTO tab (col1, col2) VALUES (2, DEFAULT);"parameterized insert::{ let manipulation :: Manipulation '[ "tab" ::: '[] :=>/ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint42 , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ]]/ '[ 'NotNull 'PGint4, 'NotNull 'PGint4 ] '[] manipulation = insertRow_ #tabE (Set (param @1) `As` #col1 :* Set (param @2) `As` #col2 :* Nil)"in renderManipulation manipulation:}C"INSERT INTO tab (col1, col2) VALUES (($1 :: int4), ($2 :: int4));"returning insert::{ let manipulation :: Manipulation '[ "tab" ::: '[] :=>/ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint44 , "col2" ::: 'Def :=> 'NotNull 'PGint4 ]] '[]& '["fromOnly" ::: 'NotNull 'PGint4] manipulation =B insertRow #tab (Set 2 `As` #col1 :* Default `As` #col2 :* Nil)A OnConflictDoRaise (Returning (#col1 `As` #fromOnly :* Nil))"in renderManipulation manipulation:}N"INSERT INTO tab (col1, col2) VALUES (2, DEFAULT) RETURNING col1 AS fromOnly;"upsert::{let manipulation :: Manipulation '[ "tab" ::: '[] :=>/ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint42 , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ]]& '[] '[ "sum" ::: 'NotNull 'PGint4] manipulation = insertRows #tab3 (Set 2 `As` #col1 :* Set 4 `As` #col2 :* Nil)3 [Set 6 `As` #col1 :* Set 8 `As` #col2 :* Nil] (OnConflictDoUpdate4 (Set 2 `As` #col1 :* Same `As` #col2 :* Nil) [#col1 .== #col2])4 (Returning $ (#col1 + #col2) `As` #sum :* Nil)"in renderManipulation manipulation:}"INSERT INTO tab (col1, col2) VALUES (2, 4), (6, 8) ON CONFLICT DO UPDATE SET col1 = 2 WHERE (col1 = col2) RETURNING (col1 + col2) AS sum;" query insert::{let manipulation :: Manipulation '[ "tab" ::: '[] :=>/ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4/ , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ] , "other_tab" ::: '[] :=>/ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4/ , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ] ] '[] '[] manipulation =  insertQuery_ #tab6 (selectStar (from (table (#other_tab `As` #t))))"in renderManipulation manipulation:}/"INSERT INTO tab SELECT * FROM other_tab AS t;"update::{ let manipulation :: Manipulation '[ "tab" ::: '[] :=>/ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint4: , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ]] '[] '[] manipulation == update_ #tab (Set 2 `As` #col1 :* Same `As` #col2 :* Nil) (#col1 ./= #col2)"in renderManipulation manipulation:}/"UPDATE tab SET col1 = 2 WHERE (col1 <> col2);"delete::{ let manipulation :: Manipulation '[ "tab" ::: '[] :=>/ '[ "col1" ::: 'NoDef :=> 'NotNull 'PGint46 , "col2" ::: 'NoDef :=> 'NotNull 'PGint4 ]] '[]" '[ "col1" ::: 'NotNull 'PGint4$ , "col2" ::: 'NotNull 'PGint4 ]@ manipulation = deleteFrom #tab (#col1 .== #col2) ReturningStar"in renderManipulation manipulation:}2"DELETE FROM tab WHERE (col1 = col2) RETURNING *;" Convert a i into a .Insert multiple rows.\When a table is created, it contains no data. The first thing to do before a database can be of much use is to insert data. Data is conceptually inserted one row at a time. Of course you can also insert more than one row, but there is no way to insert less than one row. Even if you know only some column values, a complete row must be created.Insert a single row.Insert multiple rows returning # and raising an error on conflicts.Insert a single row returning # and raising an error on conflicts. Insert a i. Insert a i returning # and raising an error on conflicts. Render a . Render a .An ] command changes the values of the specified columns in all rows that satisfy the condition.Update a row returning .Delete rows of a table.Delete rows returning . provides a way to write auxiliary statements for use in a larger statement. These statements, which are often referred to as Common Table Expressions or CTEs, can be thought of as defining temporary tables that exist just for one statement.otype ProductsTable = '[] :=> '["product" ::: 'NoDef :=> 'NotNull 'PGtext, "date" ::: 'Def :=> 'NotNull 'PGdate]:{let} manipulation :: Manipulation '["products" ::: ProductsTable, "products_deleted" ::: ProductsTable] '[ 'NotNull 'PGdate] '[] manipulation = withV (deleteFrom #products (#date .< param @1) ReturningStar `As` #deleted_rows :* Nil)X (insertQuery_ #products_deleted (selectStar (from (table (#deleted_rows `As` #t)))))"in renderManipulation manipulation:}"WITH deleted_rows AS (DELETE FROM products WHERE (date < ($1 :: date)) RETURNING *) INSERT INTO products_deleted SELECT * FROM deleted_rows AS t;" table to insert into row to insertmore rows to insert)what to do in case of constraint conflictresults to returntable to insert into row to insert)what to do in case of constraint conflictresults to returntable to insert into row to insertmore rows to inserttable to insert into row to inserttable to insert into)what to do in case of constraint conflictresults to returntable to insert intotable to update%modified values to replace old values0condition under which to perform update on a rowresults to returntable to update%modified values to replace old values0condition under which to perform update on a rowtable to delete from%condition under which to delete a rowresults to returntable to delete from%condition under which to delete a rowcommon table expressionsSqueal data definition language(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&'+,-016;<=>?FKQSTV]hH&An 8 describes the alteration to perform on a single column.An  is either NULL or has DEFAULT.S adds a new column, initially filled with whatever default value is given or with NULL.:{ let definition :: Definition? '["tab" ::: '[] :=> '["col1" ::: 'NoDef :=> 'Null 'PGint4]] '["tab" ::: '[] :=>- '[ "col1" ::: 'NoDef :=> 'Null 'PGint4. , "col2" ::: 'Def :=> 'Null 'PGtext ]]H definition = alterTable #tab (addColumn #col2 (text & default_ "foo"))in renderDefinition definition:}6"ALTER TABLE tab ADD COLUMN col2 text DEFAULT E'foo';":{ let definition :: Definition? '["tab" ::: '[] :=> '["col1" ::: 'NoDef :=> 'Null 'PGint4]] '["tab" ::: '[] :=>- '[ "col1" ::: 'NoDef :=> 'Null 'PGint40 , "col2" ::: 'NoDef :=> 'Null 'PGtext ]]5 definition = alterTable #tab (addColumn #col2 text)in renderDefinition definition:}'"ALTER TABLE tab ADD COLUMN col2 text;"An @ describes the alteration to perform on the columns of a table. Analagous to  there is also A which is invoked when a referenced column is changed (updated).[if any referencing rows has not changed when the constraint is checked, an error is raised#prevents update of a referenced row\the updated values of the referenced column(s) should be copied into the referencing row(s)= indicates what to do with rows that reference a deleted row.Wif any referencing rows still exist when the constraint is checked, an error is raised%prevents deletion of a referenced rowospecifies that when a referenced row is deleted, row(s) referencing it should be automatically deleted as well=A type synonym for constraints on a table with a foreign key.Column columns column is a witness that column is in columns. Data types are a way to limit the kind of data that can be stored in a table. For many applications, however, the constraint they provide is too coarse. For example, a column containing a product price should probably only accept positive values. But there is no standard data type that accepts only positive numbers. Another issue is that you might want to constrain column data with respect to other columns or rows. For example, in a table containing product information, there should be only one row for each product number. Ls give you as much control over the data in your tables as you wish. If a user attempts to store data in a column that would violate a constraint, an error is raised. This applies even if the value came from the default value definition.A A is a statement that changes the schema of the database, like a , , or  command. s may be composed using the  operator. adds a table to the schema.:set -XOverloadedLabels:{renderDefinition $; createTable #tab (int `As` #a :* real `As` #b :* Nil) Nil:}#"CREATE TABLE tab (a int, b real);" creates a table if it doesn't exist, but does not add it to the schema. Instead, the schema already has the table so if the table did not yet exist, the schema was wrong. H fixes this. Interestingly, this property makes it an idempotent in the  .*:set -XOverloadedLabels -XTypeApplications\type Table = '[] :=> '["a" ::: 'NoDef :=> 'Null 'PGint4, "b" ::: 'NoDef :=> 'Null 'PGfloat4] type Schema = '["tab" ::: Table]:{renderDefinitiond (createTableIfNotExists #tab (int `As` #a :* real `As` #b :* Nil) Nil :: Definition Schema Schema):}1"CREATE TABLE IF NOT EXISTS tab (a int, b real);" Render a .A  constraint is the most generic Lu type. It allows you to specify that the value in a certain column must satisfy a Boolean (truth-value) expression.:{renderDefinition $ createTable #tab ( (int & notNull) `As` #a :*& (int & notNull) `As` #b :* Nil )P ( check (Column #a :* Column #b :* Nil) (#a .> #b) `As` #inequality :* Nil ):}["CREATE TABLE tab (a int NOT NULL, b int NOT NULL, CONSTRAINT inequality CHECK ((a > b)));"A z constraint ensure that the data contained in a column, or a group of columns, is unique among all the rows in the table.:{renderDefinition $ createTable #tab ( int `As` #a :* int `As` #b :* Nil )B ( unique (Column #a :* Column #b :* Nil) `As` #uq_a_b :* Nil ):}C"CREATE TABLE tab (a int, b int, CONSTRAINT uq_a_b UNIQUE (a, b));"A  constraint indicates that a column, or group of columns, can be used as a unique identifier for rows in the table. This requires that the values be both unique and not null.:{renderDefinition $ createTable #tab ( serial `As` #id :** (text & notNull) `As` #name :* Nil )9 ( primaryKey (Column #id :* Nil) `As` #pk_id :* Nil ):}V"CREATE TABLE tab (id serial, name text NOT NULL, CONSTRAINT pk_id PRIMARY KEY (id));"A  specifies that the values in a column (or a group of columns) must match the values appearing in some row of another table. We say this maintains the referential integrity between two related tables.:{ type Schema = '[ "users" :::2 '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>, '[ "id" ::: 'Def :=> 'NotNull 'PGint40 , "name" ::: 'NoDef :=> 'NotNull 'PGtext ] , "emails" :::. '[ "pk_emails" ::: 'PrimaryKey '["id"]C , "fk_user_id" ::: 'ForeignKey '["user_id"] "users" '["id"] ] :=>, '[ "id" ::: 'Def :=> 'NotNull 'PGint43 , "user_id" ::: 'NoDef :=> 'NotNull 'PGint4. , "email" ::: 'NoDef :=> 'Null 'PGtext ] ]:}:{let setup :: Definition '[] Schema setup =  createTable #users ( serial `As` #id :*+ (text & notNull) `As` #name :* Nil )A ( primaryKey (Column #id :* Nil) `As` #pk_users :* Nil ) >>> createTable #emails ( serial `As` #id :*' (int & notNull) `As` #user_id :* text `As` #email :* Nil )8 ( primaryKey (Column #id :* Nil) `As` #pk_emails :*E foreignKey (Column #user_id :* Nil) #users (Column #id :* Nil)B OnDeleteCascade OnUpdateCascade `As` #fk_user_id :* Nil )in renderDefinition setup:},"CREATE TABLE users (id serial, name text NOT NULL, CONSTRAINT pk_users PRIMARY KEY (id)); CREATE TABLE emails (id serial, user_id int NOT NULL, email text, CONSTRAINT pk_emails PRIMARY KEY (id), CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE);"Render .Render .! removes a table from the schema.'renderDefinition $ dropTable #muh_table"DROP TABLE muh_table;"3 changes the definition of a table from the schema.- changes the name of a table from the schema.-renderDefinition $ alterTableRename #foo #bar "ALTER TABLE foo RENAME TO bar;"An  adds a table constraint.:{let definition :: DefinitionA '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4]]^ '["tab" ::: '["positive" ::: Check '["col"]] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4]]a definition = alterTable #tab (addConstraint #positive (check (Column #col :* Nil) (#col .> 0)))in renderDefinition definition:}<"ALTER TABLE tab ADD CONSTRAINT positive CHECK ((col > 0));"A  drops a table constraint.:{let definition :: Definition^ '["tab" ::: '["positive" ::: Check '["col"]] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4]]A '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4]]9 definition = alterTable #tab (dropConstraint #positive)in renderDefinition definition:}+"ALTER TABLE tab DROP CONSTRAINT positive;"A  removes a column. Whatever data was in the column disappears. Table constraints involving the column are dropped, too. However, if the column is referenced by a foreign key constraint of another table, PostgreSQL will not silently drop that constraint.:{ let definition :: Definition '["tab" ::: '[] :=>- '[ "col1" ::: 'NoDef :=> 'Null 'PGint40 , "col2" ::: 'NoDef :=> 'Null 'PGtext ]]? '["tab" ::: '[] :=> '["col1" ::: 'NoDef :=> 'Null 'PGint4]]1 definition = alterTable #tab (dropColumn #col2)in renderDefinition definition:}#"ALTER TABLE tab DROP COLUMN col2;"A  renames a column.:{let definition :: Definition> '["tab" ::: '[] :=> '["foo" ::: 'NoDef :=> 'Null 'PGint4]]> '["tab" ::: '[] :=> '["bar" ::: 'NoDef :=> 'Null 'PGint4]]7 definition = alterTable #tab (renameColumn #foo #bar)in renderDefinition definition:}+"ALTER TABLE tab RENAME COLUMN foo TO bar;"An  alters a single column.A  sets a new default for a column. Note that this doesn't affect any existing rows in the table, it just changes the default for future insert and update commands.:{let definition :: Definition> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]]< '["tab" ::: '[] :=> '["col" ::: 'Def :=> 'Null 'PGint4]]@ definition = alterTable #tab (alterColumn #col (setDefault 5))in renderDefinition definition:}1"ALTER TABLE tab ALTER COLUMN col SET DEFAULT 5;"A ( removes any default value for a column.:{let definition :: Definition< '["tab" ::: '[] :=> '["col" ::: 'Def :=> 'Null 'PGint4]]> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]]= definition = alterTable #tab (alterColumn #col dropDefault)in renderDefinition definition:}0"ALTER TABLE tab ALTER COLUMN col DROP DEFAULT;"A  adds a NOT NULL constraint to a column. The constraint will be checked immediately, so the table data must satisfy the constraint before it can be added.:{let definition :: Definition> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]]A '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4]]< definition = alterTable #tab (alterColumn #col setNotNull)in renderDefinition definition:}0"ALTER TABLE tab ALTER COLUMN col SET NOT NULL;"A  drops a NOT NULL constraint from a column.:{let definition :: DefinitionA '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4]]> '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint4]]= definition = alterTable #tab (alterColumn #col dropNotNull)in renderDefinition definition:}1"ALTER TABLE tab ALTER COLUMN col DROP NOT NULL;"An  converts a column to a different data type. This will succeed only if each existing entry in the column can be converted to the new type by an implicit cast.:{ let definition :: DefinitionA '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGint4]]D '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'NotNull 'PGnumeric]] definition =F alterTable #tab (alterColumn #col (alterType (numeric & notNull)))in renderDefinition definition:}9"ALTER TABLE tab ALTER COLUMN col TYPE numeric NOT NULL;" column to addtype of the new columnthe name of the table to add%the names and datatype of each column(constraints that must hold for the tablethe name of the table to add%the names and datatype of each column(constraints that must hold for the tablethe name of the table to add%the names and datatype of each column(constraints that must hold for the tablecondition to check!unique column or group of columns&identifying column or group of columnscolumn or columns in the tablereference table2reference column or columns in the reference table$what to do when reference is deleted$what to do when reference is updatedtable to removetable to alteralteration to performtable to renamewhat to rename itconstraint to addconstraint to dropcolumn to removecolumn to renamewhat to rename the columncolumn to alteralteration to performdefault value to set// Binary encoding and decoding(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&'+,-34567;<=>?FSTV]hL   A is a 1-tuple type, useful for encoding a single parameter with ! or decoding a single value with .import Data.TextDtoParams @(Only (Maybe Text)) @'[ 'Null 'PGtext] (Only (Just "foo"))K (Just "foo") :* NilUfromRow @'["fromOnly" ::: 'Null 'PGtext] @(Only (Maybe Text)) (K (Just "bar") :* Nil)Only {fromOnly = Just "bar"}A D constraint generically sequences the parsings of the columns of a F into the fields of a record N provided they have the same field names. You should not define instances of . Instead define  and " instances which in turn provide  instances. :set -XOverloadedStringsimport Data.Text<newtype UserId = UserId { getUserId :: Int16 } deriving ShowKinstance FromValue 'PGint2 UserId where fromValue = fmap UserId . fromValue`data UserRow = UserRow { userId :: UserId, userName :: Maybe Text } deriving (Show, GHC.Generic)instance Generic UserRow instance HasDatatypeInfo UserRowJtype User = '["userId" ::: 'NotNull 'PGint2, "userName" ::: 'Null 'PGtext]LfromRow @User @UserRow (K (Just "\NUL\SOH") :* K (Just "bloodninja") :* Nil)GUserRow {userId = UserId {getUserId = 1}, userName = Just "bloodninja"}A  constraint lifts the  parser to a decoding of a (Symbol, ColumnType) to a  , decoding Ys to (s. You should not define instances for ", just use the provided instances.(:set -XTypeOperators -XOverloadedStrings0newtype Id = Id { getId :: Int16 } deriving ShowCinstance FromValue 'PGint2 Id where fromValue = fmap Id . fromValueGfromColumnValue @("col" ::: 'NotNull 'PGint2) @Id (K (Just "\NUL\SOH"))Id {getId = 1}LfromColumnValue @("col" ::: 'Null 'PGint2) @(Maybe Id) (K (Just "\NUL\SOH"))Just (Id {getId = 1})A C constraint gives a parser from the binary format of a PostgreSQL ] into a Haskell .0newtype Id = Id { getId :: Int16 } deriving ShowCinstance FromValue 'PGint2 Id where fromValue = fmap Id . fromValueA 3 constraint generically sequences the encodings of 2s of the fields of a tuple or record to a row of R's. You should not define instances of . Instead define " instances which in turn provide  instances.1type Params = '[ 'NotNull 'PGbool, 'Null 'PGint2]RtoParams @(Bool, Maybe Int16) @'[ 'NotNull 'PGbool, 'Null 'PGint2] (False, Just 0)-K (Just "\NUL") :* K (Just "\NUL\NUL") :* Nil:set -XDeriveGenericHdata Tuple = Tuple { p1 :: Bool, p2 :: Maybe Int16} deriving GHC.Genericinstance Generic Tuple.toParams @Tuple @Params (Tuple False (Just 0))-K (Just "\NUL") :* K (Just "\NUL\NUL") :* NilA  constraint lifts the  encoding of a  to a R , encoding s to Y's. You should not define instances of ", just use the provided instances.*toColumnParam @Int16 @('NotNull 'PGint2) 0K (Just "\NUL\NUL")6toColumnParam @(Maybe Int16) @('Null 'PGint2) (Just 0)K (Just "\NUL\NUL")5toColumnParam @(Maybe Int16) @('Null 'PGint2) Nothing K NothingA + constraint gives an encoding of a Haskell . into into the binary format of a PostgreSQL ].#:set -XTypeApplications -XDataKindstoParam @Bool @'PGbool FalseK "\NUL"toParam @Int16 @'PGint2 0 K "\NUL\NUL"toParam @Int32 @'PGint4 0K "\NUL\NUL\NUL\NUL":set -XMultiParamTypeClasses0newtype Id = Id { getId :: Int16 } deriving Show;instance ToParam Id 'PGint2 where toParam = toParam . getIdtoParam @Id @'PGint2 (Id 1) K "\NUL\SOH"      PQ monad(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone,-37;<=>?ADFQSTVh]A snapshot of the state of a o computation.^^ is an mtl style constraint, similar to %& , for using LibPQ to _ runs a # with params from a type with a  constraint. It calls # and doesn't afraid of anything.` is like _ for a parameter-free statement.a is like _ for query statements.b is like a for a parameter-free statement.c3 has the same type signature as a composition of  and _@ but provides an optimization by preparing the statement with  and then traversing a  container with 9. The temporary prepared statement is then deallocated.d is a flipped ce is like c but works on  containers and returns unit.f is a flipped e.g lets you lift actions from LibPQ- that require a connection into your monad.5To define an instance, you can minimally define only _, c, e and g,. Monad transformers get a default instance.hAn  (https://bentnib.org/paramnotions-jfp.pdfAtkey indexed monad is a   /https://ncatlab.org/nlab/show/enriched+categoryenriched category-. An indexed monad transformer transforms a  into an indexed monad. And, hA is a class for indexed monad transformers that support running s using n7 and embedding a computation in a larger schema using m.iindexed analog of jindexed analog of kindexed analog of lindexed analog of flipped m.Safely embed a computation in a larger schema.nRun a  with $, we expect that libpq obeys the law Sdefine statement1 & pqThen (define statement2) = define (statement1 >>> statement2)oKWe keep track of the schema via an Atkey indexed state monad transformer, o.r.Makes a new connection to the database server.bThis function opens a new database connection using the parameters taken from the string conninfo.The passed string can be empty to use all default parameters, or it can contain one or more parameter settings separated by whitespace. Each parameter setting is in the form keyword = value. Spaces around the equal sign are optional. To write an empty value or a value containing spaces, surround it with single quotes, e.g., keyword = 'a value'. Single quotes and backslashes within the value must be escaped with a backslash, i.e., ' and .ETo specify the schema you wish to connect with, use type application.:set -XDataKinds:set -XPolyKinds:set -XTypeOperatorsHtype Schema = '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint2]]:set -XTypeApplications:set -XOverloadedStringsEconn <- connectdb @Schema "host=localhost port=5432 dbname=exampledb"^Note that, for now, squeal doesn't offer any protection from connecting with the wrong schema!s$Closes the connection to the server.tDo r and s before and after a computation.uSafely u to a smaller schema.vRun a o and keep the result and the  Connection. w Execute a o% and discard the result but keep the  Connection. x Evaluate a o and discard the  Connection but keep the result.yHelper function in defining  instance for o.z5Get a row corresponding to a given row number from a <, throwing an exception if the row number is out of bounds.{:Intended to be used for unfolding in streaming libraries, {8 takes a total number of rows (which can be found with  ) and a 2 and given a row number if it's too large returns >, otherwise returning the row along with the next row number.|Get all rows from a .}%Get the first row if possible from a .~Lifts actions on results from LibPQ.8Returns the number of rows (tuples) in the query result.)Returns the result status of the command.UReturns the error message most recently generated by an operation on the connection. _,  or ar and friendsbr and friendsc, , or  , and friendsd,  or e,  or f,  or rconninfoz row numberresult{total number of rowsresult row number|result}result3 ]^_`abcdefghijklmnopqrstuvwxyz{|}~7rstuopqvwxhijklmn^__`abccdeefgg]yz|{}~ ^ __`abccdeefgghijklmnopqPooled connections(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone,-3;<=>?FQTVW A snapshot of the state of a  computation. schema% should be a drop-in replacement for o  schema schema.Create a striped pool of connections. Although the garbage collector will destroy all idle connections when the pool is garbage collected it's recommended to manually Y when you're done with the pool so that the connections are freed up as soon as possible.Helper function in defining  instance for . instance for .^ instance for . instance for . instance for . instance for . instance for .The passed string can be empty to use all default parameters, or it can contain one or more parameter settings separated by whitespace. Each parameter setting is in the form keyword = value. Spaces around the equal sign are optional. To write an empty value or a value containing spaces, surround it with single quotes, e.g., keyword = 'a value'. Single quotes and backslashes within the value must be escaped with a backslash, i.e., ' and .[The number of stripes (distinct sub-pools) to maintain. The smallest acceptable value is 1.Amount of time for which an unused connection is kept open. The smallest acceptable value is 0.5 seconds. The elapsed time before destroying a connection may be a little longer than requested, as the reaper thread wakes at 1-second intervals.Maximum number of connections to keep open per stripe. The smallest acceptable value is 1. Requests for connections will block if this limit is reached on a single stripe, even if other stripes have idle connections available. #Squeal transaction control language(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone,-;<=>?FTV]c!The D transaction property has no effect unless the transaction is also  and . When all three of these properties are selected for a transaction, the transaction may block when first acquiring its snapshot, after which it is able to run without the normal overhead of a j transaction and without any risk of contributing to or being canceled by a serialization failure. This 4 is well suited for long-running reports or backups.BThe transaction access mode determines whether the transaction is  or . ' is the default. When a transaction is /, the following SQL commands are disallowed: INSERT, UPDATE, DELETE, and  COPY FROMB if the table they would write to is not a temporary table; all CREATE, ALTER, and DROP commands; COMMENT, GRANT, REVOKE, TRUNCATE; and EXPLAIN ANALYZE and EXECUTEZ if the command they would execute is among those listed. This is a high-level notion of * that does not prevent all writes to disk.SThe SQL standard defines four levels of transaction isolation. The most strict is h, which is defined by the standard in a paragraph which says that any concurrent execution of a set of ; transactions is guaranteed to produce the same effect as running them one at a time in some order. The other three levels are defined in terms of phenomena, resulting from interaction between concurrent transactions, which must not occur at each level. The phenomena which are prohibited at various levels are: Dirty readK: A transaction reads data written by a concurrent uncommitted transaction.Nonrepeatable read: A transaction re-reads data it has previously read and finds that data has been modified by another transaction (that committed since the initial read). Phantom read: A transaction re-executes a query returning a set of rows that satisfy a search condition and finds that the set of rows satisfying the condition has changed due to another recently-committed transaction.Serialization anomaly: The result of successfully committing a group of transactions is inconsistent with all possible orderings of running those transactions one at a time.In PostgreSQL, you can request any of the four standard transaction isolation levels, but internally only three distinct isolation levels are implemented, i.e. PostgreSQL's  mode behaves like . This is because it is the only sensible way to map the standard isolation levels to PostgreSQL's multiversion concurrency control architecture.Dirty read is not possible. Nonrepeatable read is not possible. Phantom read is not possible. Serialization anomaly is not possible.Dirty read is not possible. Nonrepeatable read is not possible. Phantom read is not possible. Serialization anomaly is possible.|Dirty read is not possible. Nonrepeatable read is possible. Phantom read is possible. Serialization anomaly is possible.|Dirty read is not possible. Nonrepeatable read is possible. Phantom read is possible. Serialization anomaly is possible.>The available transaction characteristics are the transaction , the transaction  ( or  ), and the .#Run a schema invariant computation .#Run a schema invariant computation  in .BEGIN a transaction.COMMIT a schema invariant transaction.ROLLBACK a schema invariant transaction."Run a schema changing computation ."Run a schema changing computation  in  DefaultMode. with a  ,   and  . with a  ,   and  @. This mode is well suited for long-running reports or backups. Render a . Render an . Render an . Render a .run inside a transactionrun inside a transaction'Squeel export module(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLNMOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvw     MNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  ]^_`abcdefghijklmnopqrstuvwxyz{|}~ Squeal migrations(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&',-<FSTV]bh0Y The I for a Squeal migration.An ) is a type-aligned list or free category.A $ should contain an inverse pair of  and  instructions and a unique .The  of a . Each  in a  should be unique.The  instruction of a .The  instruction of a .A  step.Run s by creating the @ if it does not exist and then in a transaction, for each each  query to see if the ( is executed. If not, then execute the  and insert its row in the .Rewind s by creating the @ if it does not exist and then in a transaction, for each each  query to see if the ) is executed. If it is, then rewind the  and delete its row in the . Creates a  if it does not already exist. Inserts a  into the  Deletes a  from the  Selects a  from the /, returning the time at which it was executed.migrations to runmigrations to rewind7()*()+(,-(./01201301456756856956:56;56<56=56>56?56@56A56B56C5DEFGHFGIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkllmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-. / / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ "                                                     ((((((((#  (  (, 0056(56(56(((((( (!56"#$%&'()*+(, -.,squeal-postgresql-0.2-Hu5Q40gnSDYJCVtMQZUaR5Squeal.PostgreSQL.SchemaSqueal.PostgreSQL.DefinitionSqueal.PostgreSQL.ExpressionSqueal.PostgreSQL.PQSqueal.PostgreSQL.PoolSqueal.PostgreSQL.RenderSqueal.PostgreSQL.QuerySqueal.PostgreSQL.ManipulationSqueal.PostgreSQL.BinarySqueal.PostgreSQL.TransactionSqueal.PostgreSQL.MigrationGenerics.SOP.Type.Metadata DatatypeInfo FieldInfoalterTableRename renameColumn alterTable alterColumn dropTable dropColumn createTable addColumn FromClause Expressiondiv_mod_ Data.ListelemgroupSqueal.PostgreSQL.Manipulations ManipulationmanipulateParams queryParamstraversePrepared Data.Maybe fromMaybeControl.Monad.State.Class MonadStateSqueal.PostgreSQLbaseGHC.OverloadedLabelsIsLabel fromLabelControl.Category>>> Data.Function&+generics-sop-0.3.2.0-DVZ1EAz7WZT3T0121HR4y2Generics.SOP.NP:*NilNP/postgresql-libpq-0.9.4.1-4skptSXJoce1cqZYLdCyBPDatabase.PostgreSQL.LibPQResult SingleTuple FatalError NonfatalError BadResponseCopyBothCopyInCopyOutTuplesOk CommandOk EmptyQuery ExecStatusRow"Database.PostgreSQL.LibPQ.Internal Connection,resource-pool-0.2.3.2-BJ5hWAPEhQ4KgSNiAIozhL Data.PooldestroyAllResourcesPool parenthesized<+>commaSeparatedrenderCommaSeparatedrenderCommaSeparatedMaybe renderNatDropIfConstraintsInvolveConstraintInvolves SameFields SameFieldRenameAlterDropCreateJoinNullifyRelationsNullifyRelation NullifyType NotAllNull AllNotNull SameTypesPGTypeOf PGIntegral PGFloatingPGNumInElem IsQualified!Has HasUnique AliasesOfAliasedAsAlias GroupedByGrouping UngroupedGroupedRelationsToTablesTablesToRelationsTableToColumnsRelationToColumnsColumnsToRelation RelationsType NilRelation RelationType NilTables TablesType TableTypeNilTableConstraintsTableConstraintsTableConstraintCheckUnique PrimaryKey ForeignKey ColumnsType ColumnTypeColumnConstraintDefNoDef::::=> NullityTypeNullNotNullHasOidoidPGTypePGboolPGint2PGint4PGint8 PGnumericPGfloat4PGfloat8PGchar PGvarcharPGtextPGbytea PGtimestamp PGtimestamptzPGdatePGtimePGtimetz PGintervalPGuuidPGinetPGjsonPGjsonb PGvararray PGfixarray UnsafePGType renderAliasrenderAliasedAs$fHasOidPGjsonb$fHasOidPGjson$fHasOidPGinet$fHasOidPGuuid$fHasOidPGinterval$fHasOidPGtimetz$fHasOidPGtime$fHasOidPGdate$fHasOidPGtimestamptz$fHasOidPGtimestamp$fHasOidPGbytea$fHasOidPGtext$fHasOidPGvarchar$fHasOidPGchar$fHasOidPGfloat8$fHasOidPGfloat4$fHasOidPGnumeric$fHasOidPGint8$fHasOidPGint4$fHasOidPGint2$fHasOidPGbool$fGroupedBy[]relationcolumn:$fGroupedBy[]relationcolumn:0$fIsLabelalias1Alias$fHaskindalias:field$fHaskindalias:field0$fIsQualifiedtablecolumn(,)$fSameFieldFieldInfo(,) $fEqAlias$fGenericAlias $fOrdAlias $fShowAlias $fNFDataAlias $fOrdAliased $fEqAliased $fShowAliasedPGTypedpgtypeTypeExpressionUnsafeTypeExpressionrenderTypeExpressionTable UnsafeTable renderTablePGAvgavg avgDistinct Condition HasParameterparamUnsafeExpressionrenderExpressionnull_unNullcoalescefromNullisNull isn'tNull matchNullnullIfarraygreatestleastunsafeBinaryOp unsafeUnaryOpunsafeFunctionatan2_castquot_rem_truncround_ceiling_truefalsenot_.&&.||caseWhenThenElse ifThenElse.==./=.>=.<.<=.> currentDate currentTimecurrentTimestamp localTimelocalTimestamplowerupper charLengthlikeunsafeAggregateunsafeAggregateDistinctsum_ sumDistinctbitAndbitOrbitAndDistinct bitOrDistinctboolAndboolOrboolAndDistinctboolOrDistinct countStarcount countDistinctevery everyDistinctmax_min_ maxDistinct minDistinctboolint2smallintint4intintegerint8bigintnumericfloat4realfloat8doublePrecisionserial2 smallserialserial4serialserial8 bigserialtextchar charactervarcharcharacterVaryingbytea timestamptimestampWithTimeZonedatetimetimeWithTimeZoneintervaluuidinetjsonjsonbvararrayfixarraynotNulldefault_$fMonoidExpression$fIsStringExpression$fFloatingExpression$fFractionalExpression$fNumExpression$fMonoidExpression0%$fIsQualifiedrelationcolumnExpression$fIsLabelcolumnExpression&$fIsQualifiedrelationcolumnExpression0$fIsLabelcolumnExpression0!$fPGAvgPGTypePGintervalPGinterval$fPGAvgPGTypePGfloat8PGfloat8$fPGAvgPGTypePGfloat4PGfloat8$fPGAvgPGTypePGnumericPGnumeric$fPGAvgPGTypePGint8PGnumeric$fPGAvgPGTypePGint4PGnumeric$fPGAvgPGTypePGint2PGnumeric$fIsLabelaliasTable$fPGTypedPGfixarray$fPGTypedPGvararray$fPGTypedPGjsonb$fPGTypedPGjson$fPGTypedPGuuid$fPGTypedPGinterval$fPGTypedPGtimetz$fPGTypedPGtime$fPGTypedPGdate$fPGTypedPGtimestamptz$fPGTypedPGtimestamp$fPGTypedPGbytea$fPGTypedPGvarchar$fPGTypedPGchar$fPGTypedPGtext$fPGTypedPGfloat8$fPGTypedPGfloat4$fPGTypedPGnumeric$fPGTypedPGint8$fPGTypedPGint4$fPGTypedPGint2$fPGTypedPGbool$fHasParametern:ty$fHasParameter1:ty1$fGenericExpression$fShowExpression$fEqExpression$fOrdExpression$fNFDataExpression$fGenericTable $fShowTable $fEqTable $fOrdTable $fNFDataTable$fGenericTypeExpression$fShowTypeExpression$fEqTypeExpression$fOrdTypeExpression$fNFDataTypeExpressionSortExpressionAscDesc AscNullsFirst AscNullsLastDescNullsFirst DescNullsLast HavingClauseNoHavingHaving GroupByClauseNoGroupsGroupByBy2UnsafeFromClauserenderFromClauseTableExpression fromClause whereClause groupByClause havingClause orderByClause limitClause offsetClauseQuery UnsafeQuery renderQueryunionunionAll intersect intersectAllexcept exceptAllselectselectDistinct selectStarselectDistinctStar selectDotStarselectDistinctDotStarrenderTableExpressionfromwhere_havingorderBylimitoffsettablesubquery crossJoin innerJoin leftOuterJoinrightOuterJoin fullOuterJoinrenderByrenderGroupByClauserenderHavingClauserenderSortExpression$fGenericQuery $fShowQuery $fEqQuery $fOrdQuery $fNFDataQuery$fGenericFromClause$fShowFromClause$fEqFromClause$fOrdFromClause$fNFDataFromClause$fShowSortExpression$fOrdHavingClause$fEqHavingClause$fShowHavingClause$fOrdBy$fEqBy$fShowByConflictClauseOnConflictDoRaiseOnConflictDoNothingOnConflictDoUpdateReturningClause ReturningStar Returning ColumnValueSameDefaultSetUnsafeManipulationrenderManipulationqueryStatement insertRows insertRow insertRows_ insertRow_ insertQuery insertQuery_renderReturningClauserenderConflictClauseupdateupdate_ deleteFrom deleteFrom_with$fGenericManipulation$fShowManipulation$fEqManipulation$fOrdManipulation$fNFDataManipulation AlterColumnUnsafeAlterColumnrenderAlterColumn AddColumn AlterTableUnsafeAlterTablerenderAlterTableOnUpdateClauseOnUpdateNoActionOnUpdateRestrictOnUpdateCascadeOnDeleteClauseOnDeleteNoActionOnDeleteRestrictOnDeleteCascade ForeignKeyedColumnTableConstraintExpressionUnsafeTableConstraintExpressionrenderTableConstraintExpression DefinitionUnsafeDefinitionrenderDefinitioncreateTableIfNotExistscheckunique primaryKey foreignKeyrenderOnDeleteClauserenderOnUpdateClause addConstraintdropConstraint setDefault dropDefault setNotNull dropNotNull alterType$fCategory[]Definition$fNFDataOnDeleteClause$fNFDataOnUpdateClause$fAddColumn(,)$fAddColumn(,)0$fGenericDefinition$fShowDefinition$fEqDefinition$fOrdDefinition$fNFDataDefinition"$fGenericTableConstraintExpression$fShowTableConstraintExpression$fEqTableConstraintExpression$fOrdTableConstraintExpression!$fNFDataTableConstraintExpression$fGenericOnDeleteClause$fShowOnDeleteClause$fEqOnDeleteClause$fOrdOnDeleteClause$fGenericOnUpdateClause$fShowOnUpdateClause$fEqOnUpdateClause$fOrdOnUpdateClause$fGenericAlterTable$fShowAlterTable$fEqAlterTable$fOrdAlterTable$fNFDataAlterTable$fGenericAlterColumn$fShowAlterColumn$fEqAlterColumn$fOrdAlterColumn$fNFDataAlterColumnOnlyfromOnlyFromRowfromRowFromColumnValuefromColumnValue FromValue fromValueToParamstoParams ToColumnParam toColumnParamToParamtoParam$fToParamVectorPGvararray$fToParamValuePGjsonb$fToParamValuePGjson$fToParamDiffTimePGinterval$fToParamUTCTimePGtimestamptz$fToParamLocalTimePGtimestamp$fToParam(,)PGtimetz$fToParamTimeOfDayPGtime$fToParamDayPGdate$fToParamByteStringPGbytea$fToParamByteStringPGbytea0$fToParamTextPGtext$fToParamTextPGtext0$fToParamCharPGchar$fToParamNetAddrPGinet$fToParamUUIDPGuuid$fToParamScientificPGnumeric$fToParamDoublePGfloat8$fToParamFloatPGfloat4$fToParamWord64PGint8$fToParamInt64PGint8$fToParamWord32PGint4$fToParamInt32PGint4$fToParamWord16PGint2$fToParamInt16PGint2$fToParamBoolPGbool$fToColumnParamMaybeNull$fToColumnParamxNotNull$fToParamsxtys$fFromValuePGfixarrayVector$fFromValuePGvararrayVector$fFromValuePGjsonbValue$fFromValuePGjsonValue$fFromValuePGintervalDiffTime$fFromValuePGtimestamptzUTCTime$fFromValuePGtimestampLocalTime$fFromValuePGtimetz(,)$fFromValuePGtimeTimeOfDay$fFromValuePGdateDay$fFromValuePGbyteaByteString$fFromValuePGbyteaByteString0$fFromValuePGtextText$fFromValuePGtextText0$fFromValuePGcharChar$fFromValuePGinetNetAddr$fFromValuePGuuidUUID$fFromValuePGnumericScientific$fFromValuePGfloat8Double$fFromValuePGfloat4Float$fFromValuePGint8Int64$fFromValuePGint4Int32$fFromValuePGint2Int16$fFromValuePGboolBool$fFromColumnValue(,)Maybe$fFromColumnValue(,)y$fFromRowresultsy$fHasDatatypeInfoOnly $fGenericOnly $fFunctorOnly$fFoldableOnly$fTraversableOnly$fEqOnly $fOrdOnly $fReadOnly $fShowOnly$fGenericOnly0PQRunMonadPQ manipulaterunQueryParamsrunQuery forPreparedtraversePrepared_ forPrepared_liftPQIndexedMonadTransPQpqAppqJoinpqBindpqThenpqEmbeddefinePQunPQ connectdbfinishwithConnectionlowerConnectionrunPQexecPQevalPQ pqliftWithgetRownextRowgetRowsfirstRow liftResultntuples resultStatusresultErrorMessage$fMonadBaseControlbPQ$fMonadBasebPQ $fMMonadPQ$fMonadTransPQ$fMFunctorTYPEPQ $fFunctorPQ $fMonadPQ$fApplicativePQ$fIndexedMonadTransPQPQ$fMonadPQschemaListT$fMonadPQschemaContT$fMonadPQschemaRWST$fMonadPQschemaRWST0$fMonadPQschemaExceptT$fMonadPQschemaMaybeT$fMonadPQschemaWriterT$fMonadPQschemaWriterT0$fMonadPQschemaStateT$fMonadPQschemaStateT0$fMonadPQschemaReaderT$fMonadPQschemaIdentityT$fMonadPQschemaPQ PoolPQRunPoolPQ runPoolPQcreateConnectionPoolpoolpqliftWith$fMonadBaseControlbPoolPQ$fMonadPQschemaPoolPQ$fMonadBasebPoolPQ$fMonadTransPoolPQ $fMonadPoolPQ$fApplicativePoolPQ$fFunctorPoolPQDeferrableMode Deferrable NotDeferrable AccessMode ReadWriteReadOnlyIsolationLevel SerializableRepeatableRead ReadCommittedReadUncommittedTransactionModeisolationLevel accessModedeferrableModetransactionallytransactionally_begincommitrollbacktransactionallySchematransactionallySchema_ defaultModelongRunningModerenderIsolationLevelrenderAccessModerenderDeferrableMode$fShowIsolationLevel$fEqIsolationLevel$fShowAccessMode$fEqAccessMode$fShowDeferrableMode$fEqDeferrableMode$fShowTransactionMode$fEqTransactionModeMigrationsTable AlignedListDone:>> Migrationnameupdownsingle migrateUp migrateDowncreateMigrationsinsertMigrationdeleteMigrationselectMigration$fCategorykAlignedListbytestring-0.10.8.2Data.ByteString.Internal ByteStringGHC.BaseMaybeNothingghc-prim GHC.TypesNat++GHC.Real Fractional GHC.FloatFloatingGHC.NumNumSymbolJustmaybe GHC.Classesmin GHC.TypeNats+Category renderColumnrenderCreationTypeGenerics.SOP.UniverseGenericHasDatatypeInfo execParamsData.Traversabletraverseprepare Traversable execPrepared Data.FoldableFoldableFunctorMonad<*>join=<<>>exec,monad-control-1.0.2.3-4Dn1Phj5k8rLcgnEMPHikLControl.Monad.Trans.ControlMonadBaseControl.transformers-base-0.4.4-1VJm3fYBPJpKzPx9sUQPqkControl.Monad.Base MonadBasetransformers-0.5.2.0Control.Monad.Trans.Class MonadTrans ApplicativerenderTransactionMode