`>XV      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU Pretty print helper functions(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone,DFQVh$Parenthesize a V.Concatenate two Vs with a space between. Comma separate a list of Vs. 6Comma separate the renderings of a heterogeneous list. Comma separate the W/ renderings of a heterogeneous list, dropping Xs. Render a promoted Y.  -Embedding of PostgreSQL type and alias system(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&'+,-0168;<=>?DFQSTVh_9 A   constraint proves that a   G of a record type has the same field names as the column aliases of a +.A , constraint is an equality constraint on a    and the column alias in a # 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  and  statements. is simply promoted Z and is used in JOINs in s.# is an idempotent that nullifies a *E used to nullify the left or right hand side of an outer join in a .# is an idempotent that nullifies a +.# is an idempotent that nullifies a ,. is a constraint that proves a + has some NOT NULL. is a constraint that proves a + has no NULLs.! is a constraint that proves two +%s have the same length and the same ,s. forgets about NULL and DEFAULTHasUnique alias xs x" is a constraint that proves that xs is a singleton of  alias ::: x.In x xs" is a constraint that proves that x is in xs. Analagous to , the constraint  defines 0 for a column alias qualified by a table alias.The  ) operator is used to name an expression.   is like a demoted version of #.8Just "hello" `As` #hi :: Aliased Maybe ("hi" ::: String)As (Just "hello") Alias!!*es are proxies for a type level string or [ and have an  instance so that with -XOverloadedLabels:set -XOverloadedLabels#foobar :: Alias "foobar"Alias## is like a promoted version of  R, a type level pair between an alias and some type, usually a column alias and a , or a table alias and a +.$$ is a constraint on 2 whose s have  and  functions.%% is a constraint on 2 whose s have \ and ] constraints.&& is a constraint on 2 whose  s have a ^ constraint.''( is an auxiliary namespace, created by GROUP BY clauses (%), and used for typesafe aggregation** is a kind synonym for a row of +\s. It is used as a kind for both a schema, a disjoint union of tables, and a joined table , a product of tables.++ is a kind synonym for a row of ,s.,, encodes the allowance of DEFAULT" and the only way to generate an -  is to use ,  or .-DEFAULT is allowed.DEFAULT is not allowed//: encodes the potential presence or definite absence of a NULLB allowing operations which are sensitive to such to be well typed.0NULL may be present1NULL is absent22. is the promoted datakind of PostgreSQL types.3logical Boolean (true/false)4signed two-byte integer5signed four-byte integer6signed eight-byte integer7 arbitrary precision numeric type80single precision floating-point number (4 bytes)90double precision floating-point number (8 bytes):fixed-length character string; variable-length character string< variable-length character string=binary data ("byte array")>date and time (no time zone)?"date and time, including time zone@ calendar date (year, month, day)Atime of day (no time zone)B time of day, including time zoneC time spanDuniversally unique identifierEIPv4 or IPv6 host addressFtextual JSON dataGbinary JSON data, decomposedH0an escape hatch for unsupported PostgreSQL typesIrenderAlias #alias"alias"J=let renderMaybe = fromString . maybe "Nothing" (const "Just")6renderAliased renderMaybe (Just (3::Int) `As` #an_int)"Just AS an_int"@  !"#$%&'()*+,.-/0123456789:;<=>?@ABCDEFGHIJ@23456789:;<=>?@ABCDEFGH/01,-.+*'()&$%#!"I J  !"'(),-./0123456789:;<=>?@ABCDEFGH9 Squeal expressions(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&',-016;<=>?ADFKQSTV]hrVW is a demoted version of a 2XXs are used in s and  createTable commands.[A [( constraint indicates a table reference.]A ]) from a schema without its alias with an 2 instance to call a table reference by its alias.`A constraint for 23s that you can take averages of and the resulting 2.cA c is a boolean valued m'. 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 c.dA df 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 m without aggregating.gA g is a witness to a i constraint. It's used in  and other (s to witness a subcolumns relationship.iA i7 constraint indicates an unqualified column reference. j" can only be unambiguous when the TableExpressionS the column references is unique, in which case the column may be referenced using -XOverloadedLabels. Otherwise, combined with a [5 constraint, the qualified column reference operator  may be used.kA kX 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 l3s are used to refer to the out-of-line data values.mmGs 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 cs in a number of commands.The expression syntax allows the calculation of values from primitive expression using arithmetic, logical, and other operations.p Render a g.qrenderExpression def "DEFAULT"rrenderExpression $ unDef false"FALSE"s analagous to XrenderExpression $ null_"NULL"t analagous to _renderExpression $ unNull true"TRUE"u+return the leftmost value which is not NULL6renderExpression $ coalesce [null_, unNull true] false"COALESCE(NULL, TRUE, FALSE)"v analagous to  fromMaybe using COALESCE&renderExpression $ fromNull true null_"COALESCE(NULL, TRUE)"w!renderExpression $ null_ & isNull"NULL IS NULL"x$renderExpression $ null_ & isn'tNull"NULL IS NOT NULL"y analagous to ` using IS NULL,renderExpression $ matchNull true not_ null_6"CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END"zright inverse to v#, if its arguments are equal then z gives NULL.#:set -XTypeApplications -XDataKindsGrenderExpression @_ @_ @'[_] $ fromNull false (nullIf false (param @1))0"COALESCE(NULL IF (FALSE, ($1 :: bool)), FALSE)"{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)":renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ atan2_ pi 2"atan2(pi(), 2)"#renderExpression $ true & cast int4"(TRUE :: int4)"&integer division, truncates the result7renderExpression @_ @_ @_ @(_(_ 'PGint2)) $ 5 `quot_` 2 "(5 / 2)"remainder upon integer division7renderExpression @_ @_ @_ @(_ (_ 'PGint2)) $ 5 `rem_` 2 "(5 % 2)"7renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ trunc pi "trunc(pi())"8renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ round_ pi "round(pi())":renderExpression @_ @_ @_ @(_ (_ 'PGfloat4)) $ ceiling_ pi"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)"WrenderExpression @_ @_ @_ @(_ (_ 'PGint2)) $ caseWhenThenElse [(true, 1), (false, 2)] 34"CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END"@renderExpression @_ @_ @_ @(_ (_ 'PGint2)) $ ifThenElse true 1 0""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 valuesLrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGnumeric)]] $ sum_ #col "sum(col)"SrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGnumeric)]] $ sumDistinct #col"sum(DISTINCT col)"KrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitAnd #col"bit_and(col)"JrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitOr #col "bit_or(col)"SrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitAndDistinct #col"bit_and(DISTINCT col)"RrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGint4)]] $ bitOrDistinct #col"bit_or(DISTINCT col)"LrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolAnd #col"bool_and(col)"KrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolOr #col"bool_or(col)"TrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolAndDistinct #col"bool_and(DISTINCT col)"SrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ boolOrDistinct #col"bool_or(DISTINCT col)"4A special aggregation that does not require an inputrenderExpression countStar "count(*)"@renderExpression @'[_ ::: '["col" ::: 'Optional _]] $ count #col "count(col)"HrenderExpression @'[_ ::: '["col" ::: 'Required _]] $ countDistinct #col"count(DISTINCT col)" synonym for JrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ every #col "every(col)" synonym for RrenderExpression @'[_ ::: '["col" ::: 'Required (_ 'PGbool)]] $ everyDistinct #col"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 `4hnot a true type, but merely a notational convenience for creating unique identifier columns with type `4hnot a true type, but merely a notational convenience for creating unique identifier columns with type `5hnot a true type, but merely a notational convenience for creating unique identifier columns with type `5hnot a true type, but merely a notational convenience for creating unique identifier columns with type `6hnot a true type, but merely a notational convenience for creating unique identifier columns with type `6 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 spanuniversally unique identifierIPv4 or IPv6 host addresstextual JSON databinary JSON data, decomposedused in  createTable, commands as a column constraint to ensure NULL is not presentused in  createTable2 commands as a column constraint to give a default4awhat to averagebwhat to averagernot DEFAULTtnot NULLuNULLs may be presentNULL is absentvwhat to convert NULL tow possibly NULLx possibly NULLywhat to convert NULL tofunction to perform when NULL is absentzNULL is absentNULL is absent{needs at least 1 argumentor more|needs at least 1 argumentor more}operator~operatorfunction numerator denominatortype to cast asvalue to convert numerator denominator numerator denominatorfractional numberfractional numberfractional numberlhsrhslhsrhslhsrhslhsrhslhsrhslhsrhsstring 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 aggregateVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~օmnoklijghpdefqrstuvwxyz}~{|c`ab]^_[\XYZVW VWXYZ[\]^_`abdefghijklmno444444Squeal queries(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&',-016;=>?FKSTV]h's are used by sortBy& to optionally sort the results of a 7.  or  set the sort direction of a 1 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. , ,  and p options are used to determine whether nulls appear before or after non-null values in the sort ordering of a 0 result column.A ; is used to eliminate groups that are not of interest. An ( . may only use  while a ) . must use % whose conditions are combined with . A   indicates the ' of a .. A ! indicates ( while a " indicates ). NoGroups is distinguised from  Group Nil& since no aggregation can be done on NoGroups while all output ms must be aggregated in  Group Nil.##s are used in I 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 real ] is a table from the schema.( derives a table from a 7.~A joined table is a table derived from two other (real or derived) tables according to the rules of the particular join type. ), *, +, , and -+ are available and can be nested using the J operator to match the left-to-right sequencing of their placement in SQL.t1 & CrossJoin t2.. For every possible combination of rows from t1 and t2_ (i.e., a Cartesian product), the joined table will contain a row consisting of all columns in t1 followed by all columns in t2. If the tables have n and m/ rows respectively, the joined table will have n * m rows.t1 & InnerJoin t2 on. For each row r1 of t1-, the joined table has a row for each row in t2 that satisfies the on condition with r1t1 & LeftOuterJoin t2 on;. First, an inner join is performed. Then, for each row in t1 that does not satisfy the on condition with any row in t27, a joined row is added with null values in columns of t2E. Thus, the joined table always has at least one row for each row in t1.t1 & RightOuterJoin t2 on;. First, an inner join is performed. Then, for each row in t2 that does not satisfy the on condition with any row in t17, a joined row is added with null values in columns of t1_. This is the converse of a left join: the result table will always have a row for each row in t2.t1 & FullOuterJoin t2 on;. First, an inner join is performed. Then, for each row in t1 that does not satisfy the on condition with any row in t27, a joined row is added with null values in columns of t2. Also, for each row of t2: that does not satisfy the join condition with any row in t12, a joined row with null values in the columns of t1 is added..A .4 computes a table. The table expression contains a 0" that is optionally followed by a 1, 2, 3, 4, 5 and 6s. 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.0VA table reference that can be a table name, or a derived table such as a subquery, a JOIN- construct, or complex combinations of these.1)optional search coditions, combined with . After the processing of the 0! 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 0P; this is not required, but otherwise the WHERE clause will be fairly useless.2The 2 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.3"If a table has been grouped using groupBy0, but only certain groups are of interest, the 3 can be used, much like a 1;, to eliminate groups from the result. Expressions in the 3w can refer both to grouped expressions and to ungrouped expressions (which necessarily involve an aggregate function).4The 4. is for optional sorting. When more than one u is specified, the later (right) values are used to sort rows that are equal according to the earlier (left) values.5The 5 is combined with a 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).6The 6 is combined with b 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.7VThe process of retrieving or the command to retrieve data from a database is called a 7. The @, B, D, A, C and E& commands are used to specify queries. simple query::{letH query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]* '["col" ::: 'Required ('Null 'PGint4)]2 query = selectStar (from (Table (#tab `As` #t)))in renderQuery query:}"SELECT * FROM tab AS t"restricted query::{let query :: Query '[ "tab" :::1 '[ "col1" ::: 'Required ('NotNull 'PGint4)4 , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[]- '[ "sum" ::: 'Required ('NotNull 'PGint4)0 , "col1" ::: 'Required ('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::{ letH query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]* '["col" ::: 'Required ('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::{letH query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]* '["col" ::: 'Required ('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::{ letI query :: Query '["tab" ::: '["col" ::: 'Required ('NotNull 'PGfloat8)]]& '[ 'Required ('NotNull 'PGfloat8)]/ '["col" ::: 'Required ('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" :::1 '[ "col1" ::: 'Required ('NotNull 'PGint4)4 , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[]- '[ "sum" ::: 'Required ('NotNull 'PGint4)0 , "col1" ::: 'Required ('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::{letH query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]* '["col" ::: 'Required ('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" :::4 '[ "id" ::: 'Required ('NotNull 'PGint4)8 , "price" ::: 'Required ('NotNull 'PGfloat4): , "customer_id" ::: 'Required ('NotNull 'PGint4): , "shipper_id" ::: 'Required ('NotNull 'PGint4) ] , "customers" :::1 '[ "id" ::: 'Required ('NotNull 'PGint4)3 , "name" ::: 'Required ('NotNull 'PGtext) ] , "shippers" :::1 '[ "id" ::: 'Required ('NotNull 'PGint4)3 , "name" ::: 'Required ('NotNull 'PGtext) ] ] '[]7 '[ "order_price" ::: 'Required ('NotNull 'PGfloat4)7 , "customer_name" ::: 'Required ('NotNull 'PGtext)6 , "shipper_name" ::: 'Required ('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::{letH query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]* '["col" ::: 'Required ('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::{ letH query :: Query '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]] '[]* '["col" ::: 'Required ('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)":DThe results of two queries can be combined using the set operation :!. Duplicate rows are eliminated. ;DThe results of two queries can be combined using the set operation ;2, the disjoint union. Duplicate rows are retained.<DThe results of two queries can be combined using the set operation <2, the intersection. Duplicate rows are eliminated.=DThe results of two queries can be combined using the set operation =0, the intersection. Duplicate rows are retained.>DThe results of two queries can be combined using the set operation >4, the set difference. Duplicate rows are eliminated.?DThe results of two queries can be combined using the set operation ?2, the set difference. Duplicate rows are retained.@the . in the @ 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.AvAfter the select list has been processed, the result table can be subject to the elimination of duplicate rows using A.BThe simplest kind of query is B= which emits all columns that the table expression produces.CA CU emits all columns that the table expression produces and eliminates duplicate rows.DrWhen working with multiple tables, it can also be useful to ask for all the columns of a particular table, using D.EA EQ asks for all the columns of a particular table, and eliminates duplicate rows.F Render a .GA G 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 G may be transformed by H, I, J, K, L and M , using the K operator to match the left-to-right sequencing of their placement in SQL.HA H is an endomorphism of .(s which adds a search condition to the 1.IA I is a transformation of .s which switches its ' from ( to ). Use  group Nil/ to perform a "grand total" aggregation query.JA J is an endomorphism of .(s which adds a search condition to the 3.KAn K is an endomorphism of .1s which appends an ordering to the right of the 4.LA L is an endomorphism of .s which adds to the 5.MAn M is an endomorphism of .s which adds to the 6.N Renders a &.O Renders a #.P Renders a  .Q Render a .R Render a .@ select listintermediate virtual tableA select listintermediate virtual tableBintermediate virtual tableCintermediate virtual tableDparticular virtual subtableintermediate virtual tableEparticular virtual subtableintermediate virtual tableGtable reference= !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR=789:;<=>?@ABCDE./0123456FGHIJKLM&'()*+,-N#$%O !"PQR !"#$%&'()*+,-./0123456789!Squeal data manipulation language(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&',-016FKQSTV]%h_)Columns to be updated are mentioned with a;; columns which are to remain the same are mentioned with `.`%column to remain the same upon updateacolumn to be updatedbA b> specifies an action to perform upon a constraint violation. c will raise an error. d! simply avoids inserting a row. eN updates the existing row that conflicts with the row proposed for insertion.fA f 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 e= condition was not satisfied, the row will not be returned. gq will return all columns in the row. Use `Returning Nil` in the common case where no return values are desired.iA i% lets you insert either values, free ms, or the result of a 7.jat least one row of valueslA ld is a statement which may modify data in the database, but does not alter the schema. Examples are p, t and v. A 7 is also considered a l& even though it does not modify data.o Convert a 7 into a l.pXWhen 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.simple insert::{ let manipulation :: Manipulation '[ "tab" :::0 '[ "col1" ::: 'Required ('NotNull 'PGint4); , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[] '[] manipulation =E insertInto #tab (Values (2 `As` #col1 :* 4 `As` #col2 :* Nil) [])' OnConflictDoRaise (Returning Nil)"in renderManipulation manipulation:}-"INSERT INTO tab (col1, col2) VALUES (2, 4);"parameterized insert::{let manipulation :: Manipulation '[ "tab" :::0 '[ "col1" ::: 'Required ('NotNull 'PGint4)3 , "col2" ::: 'Required ('NotNull 'PGint4) ]]# '[ 'Required ('NotNull 'PGint4)) , 'Required ('NotNull 'PGint4) ] '[] manipulation = insertInto #tabE (Values (param @1 `As` #col1 :* param @2 `As` #col2 :* Nil) [])' OnConflictDoRaise (Returning Nil)"in renderManipulation manipulation:}C"INSERT INTO tab (col1, col2) VALUES (($1 :: int4), ($2 :: int4));"returning insert::{ let manipulation :: Manipulation '[ "tab" :::0 '[ "col1" ::: 'Required ('NotNull 'PGint4)7 , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[]2 '["fromOnly" ::: 'Required ('NotNull 'PGint4)] manipulation =E insertInto #tab (Values (2 `As` #col1 :* 4 `As` #col2 :* Nil) [])A OnConflictDoRaise (Returning (#col1 `As` #fromOnly :* Nil))"in renderManipulation manipulation:}H"INSERT INTO tab (col1, col2) VALUES (2, 4) RETURNING col1 AS fromOnly;" query insert::{let manipulation :: Manipulation '[ "tab" :::0 '[ "col1" ::: 'Required ('NotNull 'PGint4)0 , "col2" ::: 'Required ('NotNull 'PGint4) ] , "other_tab" :::0 '[ "col1" ::: 'Required ('NotNull 'PGint4)0 , "col2" ::: 'Required ('NotNull 'PGint4) ] ] '[] '[] manipulation =  insertInto #tab ( ValuesQuery $8 selectStar (from (Table (#other_tab `As` #t))) )' OnConflictDoRaise (Returning Nil)"in renderManipulation manipulation:}/"INSERT INTO tab SELECT * FROM other_tab AS t;"upsert::{let manipulation :: Manipulation '[ "tab" :::0 '[ "col1" ::: 'Required ('NotNull 'PGint4)3 , "col2" ::: 'Required ('NotNull 'PGint4) ]]2 '[] '[ "sum" ::: 'Required ('NotNull 'PGint4)] manipulation = insertInto #tab (Values- (2 `As` #col1 :* 4 `As` #col2 :* Nil). [6 `As` #col1 :* 8 `As` #col2 :* Nil]) (OnConflictDoUpdate4 (Set 2 `As` #col1 :* Same `As` #col2 :* Nil)! (Just (#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;"q Render a i.r Render a f.s Render a b.tAn t] command changes the values of the specified columns in all rows that satisfy the condition.:{ let manipulation :: Manipulation '[ "tab" :::0 '[ "col1" ::: 'Required ('NotNull 'PGint4); , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[] '[] manipulation =< update #tab (Set 2 `As` #col1 :* Same `As` #col2 :* Nil)' (#col1 ./= #col2) (Returning Nil)"in renderManipulation manipulation:}/"UPDATE tab SET col1 = 2 WHERE (col1 <> col2);"u Render an _.vDelete rows of a table.:{ let manipulation :: Manipulation '[ "tab" :::0 '[ "col1" ::: 'Required ('NotNull 'PGint4)7 , "col2" ::: 'Required ('NotNull 'PGint4) ]] '[]. '[ "col1" ::: 'Required ('NotNull 'PGint4)0 , "col2" ::: 'Required ('NotNull 'PGint4) ]@ manipulation = deleteFrom #tab (#col1 .== #col2) ReturningStar"in renderManipulation manipulation:}2"DELETE FROM tab WHERE (col1 = col2) RETURNING *;"ptable to insert intovalues to insert)what to do in case of constraint conflictresults to returnttable to update%modified values to replace old values0condition under which to perform update on a rowresults to returnvtable to delete from%condition under which to delete a rowresults to return_`abcdefghijklmnopqrstuvlmnopijkqfghrbcdest_`auv_`abcdefghijklmnSqueal data definition language(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&',-016FKQSTV]"An 8 describes the alteration to perform on a single column.An @ describes the alteration to perform on the columns of a table. Analagous to OnDelete there is also OnUpdateA 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)OnDelete= 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 wellData 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. s 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) []:}#"CREATE TABLE tab (a int, b real);"A  constraint is the most generic u 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 ) [ check (#a .> #b) ]:}E"CREATE TABLE tab (a int NOT NULL, b int NOT NULL, 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 ). [ unique (Column #a :* Column #b :* Nil) ]:}1"CREATE TABLE tab (a int, b int, 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 )& [ primaryKey (Column #id :* Nil) ]:}E"CREATE TABLE tab (id serial, name text NOT NULL, 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.:{let definition :: Definition '[] '[ "users" :::/ '[ "id" ::: 'Optional ('NotNull 'PGint4)5 , "username" ::: 'Required ('NotNull 'PGtext) ] , "emails" :::/ '[ "id" ::: 'Optional ('NotNull 'PGint4)3 , "userid" ::: 'Required ('NotNull 'PGint4)2 , "email" ::: 'Required ('NotNull 'PGtext) ] ] definition = createTable #usersA (serial `As` #id :* (text & notNull) `As` #username :* Nil)* [primaryKey (Column #id :* Nil)] >>> createTable #emails ( serial `As` #id :*+ (integer & notNull) `As` #userid :*- (text & notNull) `As` #email :* Nil )& [ primaryKey (Column #id :* Nil)E , foreignKey (Column #userid :* Nil) #users (Column #id :* Nil)( OnDeleteCascade OnUpdateRestrict ]in renderDefinition definition:}"CREATE TABLE users (id serial, username text NOT NULL, PRIMARY KEY (id)); CREATE TABLE emails (id serial, userid integer NOT NULL, email text NOT NULL, PRIMARY KEY (id), FOREIGN KEY (userid) REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT);"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 :: Definition: '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]: '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]? definition = alterTableAddConstraint #tab (check (#col .> 0))in renderDefinition definition:}("ALTER TABLE tab ADD CHECK ((col > 0));"An  adds a new -R column. The new column is initially filled with whatever default value is given.:{ let definition :: Definition8 '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]] '["tab" :::. '[ "col1" ::: 'Required ('Null 'PGint4)1 , "col2" ::: 'Optional ('Null 'PGtext) ]] definition = alterTable #tab4 (addColumnDefault #col2 (text & default_ "foo"))in renderDefinition definition:}6"ALTER TABLE tab ADD COLUMN col2 text DEFAULT E'foo';"An  adds a new 02 column. The new column is initially filled with NULLs.:{ let definition :: Definition8 '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]] '["tab" :::. '[ "col1" ::: 'Required ('Null 'PGint4)1 , "col2" ::: 'Required ('Null 'PGtext) ]]9 definition = alterTable #tab (addColumnNull #col2 text)in renderDefinition definition:}'"ALTER TABLE tab ADD COLUMN col2 text;"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" ::: 'Required ('Null 'PGint4)1 , "col2" ::: 'Required ('Null 'PGtext) ]]8 '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]1 definition = alterTable #tab (dropColumn #col2)in renderDefinition definition:}#"ALTER TABLE tab DROP COLUMN col2;"Like @ but authorizes dropping everything that depends on the column.:{ let definition :: Definition '["tab" :::. '[ "col1" ::: 'Required ('Null 'PGint4)1 , "col2" ::: 'Required ('Null 'PGtext) ]]8 '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]8 definition = alterTable #tab (dropColumnCascade #col2)in renderDefinition definition:}+"ALTER TABLE tab DROP COLUMN col2 CASCADE;"A  renames a column.:{let definition :: Definition7 '["tab" ::: '["foo" ::: 'Required ('Null 'PGint4)]]7 '["tab" ::: '["bar" ::: 'Required ('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  insertTable and  updateTable commands.:{let definition :: Definition7 '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]7 '["tab" ::: '["col" ::: 'Optional ('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 :: Definition7 '["tab" ::: '["col" ::: 'Optional ('Null 'PGint4)]]7 '["tab" ::: '["col" ::: 'Required ('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 :: Definition7 '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]: '["tab" ::: '["col" ::: 'Required ('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 :: Definition: '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]7 '["tab" ::: '["col" ::: 'Required ('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 :: Definition: '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]= '["tab" ::: '["col" ::: 'Required ('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;"the 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 ittable to constrainwhat constraint to add column to addtype of the new column column to addtype of the new columncolumn to removecolumn to removecolumn to alteralteration to performdefault value to set++Binary encoding and decoding(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone&'+,-34567;<=>?FSTV]h A is a 1-tuple type, useful for encoding a single parameter with ! or decoding a single value with .import Data.TextPtoParams @(Only (Maybe Text)) @'[ 'Required ('Null 'PGtext)] (Only (Just "foo"))K (Just "foo") :* Nil=type PGShortRow = '["fromOnly" ::: 'Required ('Null 'PGtext)]@fromRow @PGShortRow @(Only (Maybe Text)) (K (Just "bar") :* Nil)Only {fromOnly = Just "bar"}A D constraint generically sequences the parsings of the columns of a + into the fields of a record cN provided they have the same field names. You should not define instances of . Instead define d and e" instances which in turn provide  instances. :set -XOverloadedStringsimport Data.Text0newtype Id = Id { getId :: Int16 } deriving ShowCinstance FromValue 'PGint2 Id where fromValue = fmap Id . fromValueVdata Hrow = Hrow { userId :: Id, userName :: Maybe Text } deriving (Show, GHC.Generic)instance Generic Hrowinstance HasDatatypeInfo Hrowctype PGrow = '["userId" ::: 'Required ('NotNull 'PGint2), "userName" ::: 'Required ('Null 'PGtext)]JfromRow @PGrow @Hrow (K (Just "\NUL\SOH") :* K (Just "bloodninja") :* Nil)<Hrow {userId = Id {getId = 1}, userName = Just "bloodninja"}A  constraint lifts the  parser to a decoding of a (Symbol, ColumnType) to a c , decoding 0s to W(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 . fromValueSfromColumnValue @("col" ::: 'Required ('NotNull 'PGint2)) @Id (K (Just "\NUL\SOH"))Id {getId = 1}XfromColumnValue @("col" ::: 'Required ('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 2 into a Haskell c.0newtype Id = Id { getId :: Int16 } deriving ShowCinstance FromValue 'PGint2 Id where fromValue = fmap Id . fromValueA 3 constraint generically sequences the encodings of c2s of the fields of a tuple or record to a row of ,'s. You should not define instances of . Instead define d" instances which in turn provide  instances.Ktype PGparams = '[ 'Required ('NotNull 'PGbool), 'Required ('Null 'PGint2)]7toParams @(Bool, Maybe Int16) @PGparams (False, Just 0)/K (Just "\NUL") :* (K (Just "\NUL\NUL") :* Nil):set -XDeriveGenericPdata Hparams = Hparams { col1 :: Bool, col2 :: Maybe Int16} deriving GHC.Genericinstance Generic Hparams4toParams @Hparams @PGparams (Hparams False (Just 0))/K (Just "\NUL") :* (K (Just "\NUL\NUL") :* Nil)A  constraint lifts the  encoding of a c to a , , encoding Ws to 0's. You should not define instances of ", just use the provided instances.6toColumnParam @Int16 @('Required ('NotNull 'PGint2)) 0K (Just "\NUL\NUL")BtoColumnParam @(Maybe Int16) @('Required ('Null 'PGint2)) (Just 0)K (Just "\NUL\NUL")AtoColumnParam @(Maybe Int16) @('Required ('Null 'PGint2)) Nothing K NothingA + constraint gives an encoding of a Haskell c. into into the binary format of a PostgreSQL 2.#: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;<=>?ADFQSTVh51getColumnNumber (columnNumber @5 @'[_,_,_,_,_,_])Col 5'In addition to being newtypes around a CInt, a  is parameterized by a Y,ural number and acts as an index into a row.Just newtypes around a CInt3Encapsulates the result of a squeal command run by LibPQ. s are parameterized by a +. describing the column names and their types.!A snapshot of the state of a , computation."" is an mtl style constraint, similar to #$ , for using LibPQ to# runs a l# with params from a type with a  constraint. It calls f# and doesn't afraid of anything.$ is like # for a parameter-free statement.% is like # for query statements.'3 has the same type signature as a composition of g and #@ but provides an optimization by preparing the statement with h and then traversing a i container with j9. The temporary prepared statement is then deallocated.( is a flipped ') is like ' but works on k containers and returns unit.* is a flipped ).+ lets you lift actions from LibPQ- that require a connection into your monad.5To define an instance, you can minimally define only #, ', ) and +,. Monad transformers get a default instance.,KWe keep track of the schema via an Atkey indexed state monad transformer, ,..A . consists of a %& '( and a phantom *0.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 -XTypeOperatorsAtype Schema = '["tab" ::: '["col" ::: 'Required ('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!1$Closes the connection to the server.2Do 0 and 1 before and after a computation.3Run a ,% and discard the result but keep the .. 4indexed analog of l5indexed analog of m6indexed analog of flipped n7Run a  with o$, we expect that libpq obeys the law Ndefine statement1 & thenDefine statement2 = define (statement1 >>> statement2)8Chain together 7 actions.9Helper function in defining p instance for ,.:JGet a single value corresponding to a given row and column number from a .;5Get a row corresponding to a given row number from a .<8Returns the number of rows (tuples) in the query result.=: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 X>, 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. #p, t or v%@ and friends&@ and friends'p, t or v(p, t or v)p, t or v*p, t or v0conninfo:rowcolresult;rowresult=total number of rowsresult row number>result?result+ !"#$%&'()*+,-./0123456789:;<=>?@/./012,-345678"##$%&''())*++!9 :;><=?@ " ##$%&''())*++,q-.r/)Squeel export module(c) Eitan Chatav, 2017eitan@morphism.tech experimentalNone8R  !"#$%&'()*+,.-/0123456789:;<=>?@ABCDEFGHIJVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR_a`bcdefghijklmnopqrstuv !"#$%&'()*+,-./0123456789:;<=>?@s*+,*+-*./*01234235236789:;<=>?@ABCDEFGHIJKLMNOPQQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMMNOPQRSTUUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~        !"#$%&'()*+,-./012344566789 :;<"=>?@AB(CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl*mn*mopqr*mspqt*uv*wx*yz*m{*|}p~*pq22****m*m*mA(/squeal-postgresql-0.1.1.2-46xUUM7R3Q1ab4nK47O4RSqueal.PostgreSQL.SchemaSqueal.PostgreSQL.DefinitionSqueal.PostgreSQL.ExpressionSqueal.PostgreSQL.PrettyprintSqueal.PostgreSQL.QuerySqueal.PostgreSQL.ManipulationSqueal.PostgreSQL.BinarySqueal.PostgreSQL.PQGenerics.SOP.Type.Metadata DatatypeInfo FieldInfoalterTableRename renameColumn alterTable alterColumn dropTable dropColumn createTableaddColumnDefault addColumnNull FromClause Expressiondiv_mod_groupdefunDefparamSqueel.PostgreSQL.DefinitionuniqueTableConstraintmanipulateParams queryParamstraversePreparedControl.Monad.State.Class MonadStateDatabase.PostgreSQLLibPQDatabase.PastgreSQL.LibPQ ConnectionSqueal.PostgreSQLbaseGHC.OverloadedLabelsIsLabel fromLabelControl.Category>>> Data.Function&+generics-sop-0.3.1.0-B0sNdk9nX4QCCChxFxgwVsGenerics.SOP.NP:*NilNP parenthesized<+>commaSeparatedrenderCommaSeparatedrenderCommaSeparatedMaybe renderNat SameFields SameFieldRenameAlterDropCreateJoin NullifyTablesNullifyColumns NullifyType NotAllNull AllNotNull SameTypesBaseType HasUniqueIn IsTableColumn!AliasedAsAlias::: PGIntegral PGFloatingPGNumGrouping UngroupedGrouped TablesType ColumnsType ColumnTypeOptionalRequired NullityTypeNullNotNullPGTypePGboolPGint2PGint4PGint8 PGnumericPGfloat4PGfloat8PGchar PGvarcharPGtextPGbytea PGtimestamp PGtimestamptzPGdatePGtimePGtimetz PGintervalPGuuidPGinetPGjsonPGjsonb UnsafePGType renderAlias renderAliased$fIsLabelalias1Alias$fIsTableColumntablecolumn(,)$fSameFieldFieldInfo(,) $fEqAlias$fGenericAlias $fOrdAlias $fShowAlias $fNFDataAlias $fOrdAliased $fEqAliased $fShowAliasedPGTypedpgtypeTypeExpressionUnsafeTypeExpressionrenderTypeExpressionHasTablegetTableTable UnsafeTable renderTablePGAvgavg avgDistinct Condition GroupedBy getGroup1 getGroup2Column HasColumn getColumn HasParameterUnsafeExpressionrenderExpression renderColumnnull_unNullcoalescefromNullisNull isn'tNull matchNullnullIfgreatestleastunsafeBinaryOp unsafeUnaryOpunsafeFunctionatan2_castquot_rem_truncround_ceiling_truefalsenot_.&&.||caseWhenThenElse ifThenElse.==./=.>=.<.<=.> currentDate currentTimecurrentTimestamp localTimelocalTimestamplowerupper charLengthlikeunsafeAggregateunsafeAggregateDistinctsum_ sumDistinctbitAndbitOrbitAndDistinct bitOrDistinctboolAndboolOrboolAndDistinctboolOrDistinct countStarcount countDistinctevery everyDistinctmax_min_ maxDistinct minDistinctboolint2smallintint4intintegerint8bigintnumericfloat4realfloat8doublePrecisionserial2 smallserialserial4serialserial8 bigserialtextchar charactervarcharcharacterVaryingbytea timestamptimestampWithTimeZonedatetimetimeWithTimeZoneintervaluuidinetjsonjsonbnotNulldefault_$fMonoidExpression$fIsStringExpression$fFloatingExpression$fFractionalExpression$fNumExpression$fIsLabelcolumnExpression$fHasColumncolumn:ty$fHasColumncolumn:Required!$fPGAvgPGTypePGintervalPGinterval$fPGAvgPGTypePGfloat8PGfloat8$fPGAvgPGTypePGfloat4PGfloat8$fPGAvgPGTypePGnumericPGnumeric$fPGAvgPGTypePGint8PGnumeric$fPGAvgPGTypePGint4PGnumeric$fPGAvgPGTypePGint2PGnumeric$fIsLabeltableTable$fHasTabletable:columns$fHasTabletable:columns0$$fIsTableColumntablecolumnExpression%$fIsTableColumntablecolumnExpression0$fIsLabelcolumnExpression0$fGroupedBytablecolumn:$fGroupedBytablecolumn:0$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$fNFDataTypeExpression $fOrdColumn $fEqColumn $fShowColumnSortExpressionAscDesc AscNullsFirst AscNullsLastDescNullsFirst DescNullsLast HavingClauseNoHavingHaving GroupByClauseNoGroupsGroupByBy2Subquery CrossJoin InnerJoin LeftOuterJoinRightOuterJoin FullOuterJoinTableExpression fromClause whereClause groupByClause havingClause orderByClause limitClause offsetClauseQuery UnsafeQuery renderQueryunionunionAll intersect intersectAllexcept exceptAllselectselectDistinct selectStarselectDistinctStar selectDotStarselectDistinctDotStarrenderTableExpressionfromwhere_havingorderBylimitoffsetrenderFromClauserenderByrenderGroupByClauserenderHavingClauserenderSortExpression$fGenericQuery $fShowQuery $fEqQuery $fOrdQuery $fNFDataQuery$fShowSortExpression$fOrdHavingClause$fEqHavingClause$fShowHavingClause$fOrdBy$fEqBy$fShowByUpdateExpressionSameSetConflictClauseOnConflictDoRaiseOnConflictDoNothingOnConflictDoUpdateReturningClause ReturningStar Returning ValuesClauseValues ValuesQuery ManipulationUnsafeManipulationrenderManipulationqueryStatement insertIntorenderValuesClauserenderReturningClauserenderConflictClauseupdaterenderUpdateExpression deleteFrom$fGenericManipulation$fShowManipulation$fEqManipulation$fOrdManipulation$fNFDataManipulation$fOrdUpdateExpression$fEqUpdateExpression$fShowUpdateExpression AlterColumnUnsafeAlterColumnrenderAlterColumn AlterColumnsUnsafeAlterColumnsrenderAlterColumnsOnUpdateClauseOnUpdateNoActionOnUpdateRestrictOnUpdateCascadeOnDeleteClauseOnDeleteNoActionOnDeleteRestrictOnDeleteCascadeUnsafeTableConstraintrenderTableConstraint DefinitionUnsafeDefinitionrenderDefinitioncheck primaryKey foreignKeyrenderOnDeleteClauserenderOnUpdateClausealterTableAddConstraintdropColumnCascade setDefault dropDefault setNotNull dropNotNull alterType$fCategory[]Definition$fNFDataOnDeleteClause$fNFDataOnUpdateClause$fGenericDefinition$fShowDefinition$fEqDefinition$fOrdDefinition$fNFDataDefinition$fGenericTableConstraint$fShowTableConstraint$fEqTableConstraint$fOrdTableConstraint$fNFDataTableConstraint$fGenericOnDeleteClause$fShowOnDeleteClause$fEqOnDeleteClause$fOrdOnDeleteClause$fGenericOnUpdateClause$fShowOnUpdateClause$fEqOnUpdateClause$fOrdOnUpdateClause$fGenericAlterColumns$fShowAlterColumns$fEqAlterColumns$fOrdAlterColumns$fNFDataAlterColumns$fGenericAlterColumn$fShowAlterColumn$fEqAlterColumn$fOrdAlterColumn$fNFDataAlterColumnOnlyfromOnlyFromRowfromRowFromColumnValuefromColumnValue FromValue fromValueToParamstoParams ToColumnParam toColumnParamToParamtoParam$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$fToColumnParamMaybeoptionality$fToColumnParamxoptionality$fToParamsxtys$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$fGenericOnly0HasColumnNumber columnNumber ColumnNumberUnsafeColumnNumbergetColumnNumber RowNumber unRowNumberResultunResultPQRunMonadPQ manipulaterunQueryParamsrunQuery forPreparedtraversePrepared_ forPrepared_liftPQPQrunPQ unConnection connectdbfinishwithConnectionexecPQpqAppqBindpqThendefine thenDefine pqliftWithgetValuegetRowntuplesnextRowgetRowsfirstRow liftResult$fMonadBaseControlbPQ$fMonadBasebPQ$fMonadTransPQ $fMonadPQ$fApplicativePQ$fMonadPQschemaListT$fMonadPQschemaContT$fMonadPQschemaRWST$fMonadPQschemaRWST0$fMonadPQschemaExceptT$fMonadPQschemaMaybeT$fMonadPQschemaWriterT$fMonadPQschemaWriterT0$fMonadPQschemaStateT$fMonadPQschemaStateT0$fMonadPQschemaReaderT$fMonadPQschemaIdentityT$fMonadPQschemaPQ$fHasColumnNumberkn:column$fHasColumnNumberk0:column1 $fFunctorPQbytestring-0.10.8.2Data.ByteString.Internal ByteStringGHC.BaseMaybeNothingghc-prim GHC.TypesNat++SymbolGHC.Real Fractional GHC.FloatFloatingGHC.NumNumJust Data.Maybemaybe GHC.Classesmin GHC.TypeNats+TypeGenerics.SOP.UniverseGenericHasDatatypeInfo/postgresql-libpq-0.9.3.1-CXlU41KFsMy8E9CIoEe7GFDatabase.PostgreSQL.LibPQ execParamsData.Traversabletraverseprepare Traversable execPrepared Data.FoldableFoldable<*>=<<>>exec,monad-control-1.0.2.2-IvdwXRXJavcAGR8n5sYUl5Control.Monad.Trans.ControlMonadBaseControl