Îõ³h,º“œ š      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ € � ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ � Ž � � ‘ ’ “ ” • – — ˜ ™ 1.7.0.0©  Safe-Inferred)*1äù'rel8Ë is a kind that parameterises aggregations. Aggregations parameterised by  are analogous to  5 (i.e, they can only produce results on a non-empty )) whereas aggregations parameterised by  are analagous to šÛ (given a non-empty) query, they return the identity values of the aggregation functions.›œ� Safe-Inferred01ÍÛùbžŸ  Safe-Inferred1ÍÚÛù¡rel8Map a  Type -> Type function over the Type1-kinded type variables in of a type constructor.¢¡None01ÂÃÄÅÆÍÚÛÝðùP£¤¥¦§¨© Safe-Inferred)*1ÃùŽª«¬­®¯°±NoneÀÒùírel8An ordering expression for a(. Primitive orderings are defined with  and , and you can combine Order via its various instances.A common pattern is to use ²1 to combine multiple orderings in sequence, and  to select individual columns.³NoneÕ´µ¶·¸ Safe-Inferred)*/0ÍùL¹º Safe-Inferredäz» Safe-Inferredù¦¼½¾ Safe-Inferred1ù׿À Safe-Inferred)*/1ÂÃÄÅÆÍØÚÛÝù¶rel8The Sqlß type class describes both null and not null database values, constrained by a specific class.For example, if you see  Sql DBEq a<, this means any database type that supports equality, and a can either be exactly an a, or it could also be Maybe a.rel8 Nullable a means that rel8 is able to check if the type a is a type that can take null values or not.rel8Homonullable a b means that both a and b can be null, or neither a or b can be null.rel8 nullify a means a cannot take null as a value. ÁÂÃÄÅÆ Safe-Inferred%&Àéòù«rel8œA name of an object (such as a table, view, function or sequence) qualified by an optional schema. In the absence of an explicit schema, the connection's  search_path will be used implicitly. rel8+The schema that this object belongs to. If Ç#, whatever is on the connection's  search_path will be used. rel8The name of the object.Èrel8 Constructs s with   set to Ç.ÉÊË  Safe-Inferred%'9ÀéòùÚ rel8âThe schema for a table. This is used to specify the name and schema that a table belongs to (the FROMÏ part of a SQL query), along with the schema of the columns within this table.ÂFor each selectable table in your database, you should provide a  TableSchema. in order to interact with the table via Rel8.rel84The columns of the table. Typically you would use a  ' data type here, parameterized by the ! context.rel8The name of the table.Ì " Safe-Inferred" Í# Safe-Inferredä5Î$ Safe-Inferred"(ìíðôjÏÐÑÒÓ% Safe-Inferred/01ÂÃÄÍØÚÛÝðù¸ÔÕ&None%'9Àéùrel81How to deserialize from PostgreSQL's text format.rel83How to deserialize from PostgreSQL's binary format.rel8Apply a parser to .ÖThis can be used if the data stored in the database should only be subset of a given :. The parser is applied when deserializing rows returned.NoneD'None%&'äéòù0rel8:How to encode a single Haskell value as an SQL expression.rel8-How to serialize to PostgreSQL's text format.rel8/How to serialize to PostgreSQL's binary format.NoneT( Safe-Inferred%&òÚrel8 A PostgreSQL type consists of a  (name, schema), and optional  and .  will usually be [], but a type like  numeric(6, 2) will have  ["6", "2"].  is always 0 for non-array types.rel83If this is an array type, the depth of that array (1 for [], 2 for [][], etc).rel8-Any modifiers applied to the underlying type.rel8"The name (and schema) of the type.Örel8 Constructs s with schema set to Ç,  set to [] and  set to 0.×)None')*òù#) rel8TypeInformationÖ describes how to encode and decode a Haskell type to and from database queries. The typeNameÖ is the name of the type in the database, which is used to accurately type literals. "rel8The name of the SQL type.#rel8ëThe delimiter that is used in PostgreSQL's text format in arrays of this type (this is almost always ',').$rel87How to deserialize a PostgreSQL result back to Haskell.%rel8/How to serialize a Haskell value to PostgreSQL.&rel8œSimultaneously map over how a type is both encoded and decoded, while retaining the name of the type. This operation is useful if you want to essentially newtype another *.ÉThe mapping is required to be total. If you have a partial mapping, see '.'rel8Apply a parser to  .ÖThis can be used if the data stored in the database should only be subset of a given  ˆ. The parser is applied when deserializing rows returned - the encoder assumes that the input data is already in the appropriate form.&' !$#%"+ Safe-Inferred)*ù#^ØÙÚ, Safe-Inferred#ŒÛ-None "%'()*äð#¸ ÜÝÞßàáâãäå.None"ð#îæ/ Safe-Inferred"ð$çèéêë0None "%ÂÃÄÝäåðù)ž(rel8äHaskell types that can be represented as expressions in a database. There should be an instance of DBType6 for all column types in your database schema (e.g., int,  timestamptz, etc).åRel8 comes with stock instances for most default types in PostgreSQL, so you should only need to derive instances of this class for custom database types, such as types defined in PostgreSQL extensions, or custom domain types.ìrel8Corresponds to inetírel8Corresponds to jsonbîrel8Corresponds to uuidïrel8Corresponds to byteaðrel8Corresponds to byteañrel8Corresponds to citextòrel8Corresponds to citextórel8Corresponds to textôrel8Corresponds to textõrel8Corresponds to intervalörel8Corresponds to time÷rel8Corresponds to  timestampørel8Corresponds to dateùrel8Corresponds to  timestamptzúrel8Corresponds to numeric(1000, log�A€A n)ûrel8Corresponds to numericürel8Corresponds to float8 and double precisionýrel8Corresponds to float4 and realþrel8Corresponds to int8ÿrel8Corresponds to int4€rel8Corresponds to int2�rel8Corresponds to char‚rel8Corresponds to bool()1None"%ðù*o*rel8ëA deriving-via helper type for column types that store a Haskell value using a JSON encoding described by aeson's ƒ and „ type classes.*+,2None"%ù*Ó-rel8Like 3, but works for jsonb columns.-./4NoneÂÃÄÅÆù+Å0rel8ÚDatabase types that can be compared for equality in queries. If a type is an instance of 0Â, it means we can compare expressions for equality using the SQL = operator.05NoneÂÃÄÅÆù-1rel8-The class of database types that support the min aggregation function.2rel8-The class of database types that support the max aggregation function.3rel8-The class of database types that support the <, <=, > and >= operators.2136None 1ÂÃÄÅÆÍÛù/ 4rel8-The class of database types that support the / operator.5rel8-The class of database types that support the / operator.6rel8�The class of database types that can be coerced to from integral expressions. This is a Rel8 concept, and allows us to provide 7.7rel8-The class of database types that support the +, *, - operators, and the abs, negate, sign functions.45678None%1=ÂÃÄÍØÚÛÝäðù3²8rel8ÔTypes that are sum types, where each constructor is unary (that is, has no fields).9rel8DBEnum: contains the necessary metadata to describe a PostgreSQL enum type.:rel87Map Haskell values to the corresponding element of the enumç type. The default implementation of this method will use the exact name of the Haskell constructors.;rel8The name of the PostgreSQL enum type that a maps to.<rel8-List of all possible values of the enum type.=rel8›A deriving-via helper type for column types that store an "enum" type (in Haskell terms, a sum type where all constructors are nullary) using a Postgres enum type.áNote that this should map to a specific type in your database's schema (explicitly created with CREATE TYPE ... AS ENUM). Use 9“ to specify the name of this Postgres type and the names of the individual values. If left unspecified, the names of the values of the Postgres enum€ are assumed to match exactly exactly the names of the constructors of the Haskell type (up to and including case sensitivity).9?:@9;:<=>8;NoneÃù3ã…†‡ˆ‰Š<None ')*1ÍÛù4ûArel8The Result7 context is the context used for decoded query results.óWhen a query is executed against a PostgreSQL database, Rel8 parses the returned rows, decoding each row into the Result context.‹Œ�Ž�A=None1ÍÛù6#Brel8/This type family is used to specify columns in Rel8ables. In  Column f a, fÄ is the context of the column (which should be left polymorphic in Rel8able definitions), and a is the type of the column.B�>None 1=ÂÃÄÅÆÈÍØÚÛÝäðù7Ñrel8)A HField type for indexing into HProduct.Crel8A HTableÆ is a functor-indexed/higher-kinded data type that is representable (’/“), constrainable (”), and specified (•).÷This is an internal concept for Rel8, and you should not need to define instances yourself or specify this constraint.?–@—A˜B™Cš›œ�žŸ ¡C¢£”“•’¤DNone)*-/13ÂÄÅÆÍØÛÝðù83 ¥¦§¨©ª«¬­®¯ENone%&')*/1<>ÀÂÄÅÆÍØÛÝäõù8ϰrel8 Transform a ± by allowing it to be null.²³´µ¶·¸°FNone %&1ÍØÛÝðù9¹º»¼½GNone01ÂÃÄÅÆÍØÚÛÝðù9X ¾¿ÀÁÂÃÄÅÆHNone-1ÂÄÅÆÍØÚÛÝðù9¦ ÇÈÉÊËÌÍÎÏÐÑINone1ÃÍÛù9çÒÓÔJNone1=ÂÃÄÅÆÈÍÚÛÝðù=‰Drel8Table¾s are one of the foundational elements of Rel8, and describe data types that have a finite number of columns. Each of these columns contains data under a shared context, and contexts describe how to interpret the metadata about a column to a particular Haskell type. In Rel8, we have contexts for expressions (the K context), aggregations (the L context), insert values (the M contex), among others.?In typical usage of Rel8 you don't need to derive instances of D. yourself, as anything that's an instance of   is always a D.Erel8The C1 functor that describes the schema of this table.Frel8=The common context that all columns use as an interpretation.Grel8The  FromExprs type family maps a type in the Expr, context to the corresponding Haskell type.NNOOPMQPÕÖרÙÚÛDEFGHJKILRNone 1ÂÄÅÆÈÍÚÛù?Qrel8Q from to a b means that a and b are D s, in the from and toÔ contexts respectively, which share the same underlying structure. In other words, b is a version of a transposed from the from context to the to context (and vice versa).QSNone 1ÂÄÅÆÍÚÛù?OÜÝÞßTNone%&')*/19<>ÀÁÂÃÄÅÆÍØÛÝäðù?¡ àáâãäåæçèéêëìUNone1ù?ÝíVNone1ù@îWNone 1ÃÅÆÍÛù@uRrel8.A special context used in the construction of Xs.ïRðYNoneÂÃÄÅÆùC5Srel8S p means that p is a kind of bifunctor on Z's that allows the mapping of a pair of W s over its underlying columns.Trel8Map a pair of Ws over p.Urel8U f means that f is a kind of functor on Z s that allows the mapping of a W over its underlying columns.Vrel8Map a W over f.Wrel8A W a b s is a special type of function a -> b whereby the resulting b> is guaranteed to be composed only from columns contained in a.Xrel8The constraint X a b ensures that W a b is a usable W.ñSTUVXW[None 'ÃÍÛÝðFç]rel89Cast an expression to a different type. Corresponds to a CAST() function call.^rel8Change the type of an \), without a cast. Even more unsafe than ],. Only use this if you are certain that the typeNames of a and b+ refer to exactly the same PostgreSQL type._rel8 Import a raw \] from opaleye, without a cast.ÛThis is an escape hatch, and can be used if Rel8 cannot adequately express the expression you need. If you find yourself using this function, please let us know, as it may indicate that something is missing from Rel8!`rel82Unsafely construct an expression from literal SQL.ÛThis is an escape hatch, and can be used if Rel8 cannot adequately express the expression you need. If you find yourself using this function, please let us know, as it may indicate that something is missing from Rel8!òóôõö÷øùúû]^`_ü^None%'ÃÍÛGÏarel8%Produce an expression from a literal.Note that you can usually use _, but litExpr6 can solve problems of inference in polymorphic code.aýþ`None)*KÆ hrel8The SQL false literal.irel8The SQL true literal.jrel8The SQL AND operator.krel8The SQL OR operator.lrel8The SQL NOT operator.mrel8Fold AND" over a collection of expressions.nrel8Fold OR" over a collection of expressions.orel8&Eliminate a boolean-valued expression.Corresponds to ab.prel8A multi-way ifthen&else statement. The first argument to caseExprÇ is a list of alternatives. The first alternative that is of the form  (true, x)Ø will be returned. If no such alternative is found, a fallback expression is returned.Corresponds to a CASE expression in SQL.qrel8 Convert a Expr (Maybe Bool) to a  Expr Bool by treating Nothing as False(. This can be useful when combined with c, which expects a BoolÌ, and produces expressions that optimize better than general case analysis. jmopqhlnikjdkefNone1ÃÍÛP[rrel8!Lift an expression that can't be null to a type that might be nullæ. This is an identity operation in terms of any generated query, and just modifies the query's type.srel8ÎAssume that a nullable column's value is non-null. If the column is actually nullï, this will lead to runtime errors when you try to decode the value into Haskell, so you should prefer to use g$ unless you know what you're doing.ÿrel8Like €, but to eliminate null.trel8Like hi , but for null.urel8Like hj , but for null.vrel8Lift an operation on non-null$ values to an operation on possibly null values. When given null,  mapNull f returns null. This is like � for ‚.wrel8Lift a binary operation on non-null; expressions to an equivalent binary operator on possibly null4 expressions. If either of the final arguments are null,  liftOpNull returns null. This is like ƒ for ‚.xrel8Corresponds to SQL null. utwvxÿ„r…†‡skNone%&ÂÃÄÅÆÍÚÛùSyrel8This type class is basically D \, where each column of the DÍ is an argument to the function, but it also has an additional instance for ()) for calling functions with no arguments.zrel8z name arguments runs the PostgreSQL function name with the arguments  arguments returning an \ a.{rel8A less safe version of z0 that does not wrap the return value in a cast.|rel8ÎConstruct an expression by applying an infix binary operator to two operands.}rel8A less safe version of |0 that does not wrap the return value in a cast.|zˆ}{ylNone1ÃÍÛSDbc‰Š‹Œ�mNone(ÝðùTYrel8ÚA deriving-via helper type for column types that store a Haskell value using a Haskell's Ž and � type classes.YZ[nNone -1ÂÃÄÅÆÍÛùTìdrel8 The class of *Øs that form a semigroup. This class is purely a Rel8 concept, and exists to mirror the  Semigroup class.erel8An associative operation.deeopNone "1ÂÃÄÅÆÍÛùU°frel8 The class of *Øs that form a semigroup. This class is purely a Rel8 concept, and exists to mirror the � class.fgqNone"1ÀÂÃÄÅÆÍÛÝðùV\rel8Typed SQL expressions.\‘rNone'ÃÍÛV9’sNone'ÂÃÄÅÆÈÍÚÛÝðùXÉ“rel8 Serializable; witnesses the one-to-one correspondence between the type sql/, which contains SQL expressions, and the type haskell:, which contains the Haskell decoding of rows containing sql SQL expressions.”rel8ToExprs exprs a is evidence that the types exprs and a* describe essentially the same type, but exprs is in the \ context, and a is a normal Haskell type.•rel8Use lit2 to turn literal Haskell values into expressions. lit is capable of lifting single Exprs to full tables.•“”“”tNone(ÃÍÛZ¦ärel8%An if-then-else expression on tables. bool x y p returns x if p is False, and returns y if p is True.årel8ÛProduce a table expression from a list of alternatives. Returns the first table where the  Expr Bool expression is True>. If no alternatives are true, the given default is returned.ærel8Like €, but to eliminate null.äåæuNoneÃÍÛù\±~rel8Like  Alternative in Haskell, some D)s form a monoid on applicative functors.rel8The identity of �.€rel8Like Altð in Haskell. This class is purely a Rel8 concept, and allows you to take a choice between two tables. See also ~.For example, using � on vÛ allows you to combine two tables and to return the first one that is a "just" MaybeTable.�rel8#An associative binary operation on Ds.€�~�dwNone)*1ÀÂÃÄÅÆÍÒØÛÝù^�‚rel8 Selects a b means that a is a schema (i.e., a D of ƒ s) for the \ columns in b.ƒrel8A Name÷ is the name of a column, as it would be defined in a table's schema definition. You can construct names by using the OverloadedStringsÒ extension and writing string literals. This is typically done when providing a  TableSchema value.•ƒ–‚xNone %'(-1ÃÍØÛÝ_¥†rel8Transform a table by adding CASTª to all columns. This is most useful for finalising a SELECT or RETURNING statement, guaranteed that the output matches what is encoded in each columns TypeInformation.—˜†™š›œ�žŸ ¡¢£yNone'(1ÂÃÄÅÆÍÛÝðb‘„rel8Construct a table in the ƒÙ context containing the names of all columns. Nested column names will be combined with /. See also: ….…rel8Construct a table in the ƒë context containing the names of all columns. The supplied function can be used to transform column names.ÃThis function can be used to generically derive the columns for a  TableSchema. For example, ómyTableSchema :: TableSchema (MyTable Name) myTableSchema = TableSchema { columns = namesFromLabelsWith last } will construct a  TableSchemaÐ where each columns names exactly corresponds to the name of the Haskell field.„…¤¥¦zNoneb»§{None'bÞ¨|None"%&')*ÃÚÛäéòùhØ ‡rel8The ON CONFLICT (...) DO UPDATE clause of an INSERT$ statement, also known as "upsert".ÃWhen an existing row conflicts with a row proposed for insertion, ON CONFLICT DO UPDATE¢ allows you to instead update this existing row. The conflicting row proposed for insertion is then "excluded", but its values can still be referenced from the SET and WHERE clauses of the UPDATE statement.ÆUpsert in Postgres a "conflict target" to be specified ”@ this is the UNIQUE½ index from conflicts with which we would like to recover. Indexes are specified by listing the columns that comprise them along with an optional predicate in the case of partial indexes.‰rel8 Which rows to select for update.Šrel8 How to update each selected row.‹rel8)An optional predicate used to specify a  + operator. Note that this differs from SQL > as null3 will sort below any other value. For a version of > that exactly matches SQL, see ñ.îrel8Corresponds to the SQL >=+ operator. Note that this differs from SQL > as null3 will sort below any other value. For a version of >= that exactly matches SQL, see ò.ïrel8Corresponds to the SQL < operator. Returns null if either arguments are null.ðrel8Corresponds to the SQL <= operator. Returns null if either arguments are null.ñrel8Corresponds to the SQL > operator. Returns null if either arguments are null.òrel8Corresponds to the SQL >= operator. Returns null if either arguments are null.órel8ÍGiven two expressions, return the expression that sorts less than the other.Corresponds to the SQL least() function.ôrel8ÐGiven two expressions, return the expression that sorts greater than the other.Corresponds to the SQL  greatest() function. ëìðïíîòñôóë‡ì‡í‡î‡ï‡ð‡ñ‡ò‡ˆNoneÈÈ—˜™šÃÄʼnNoneÈù›œ�žÆÇÈŠNone()*ÃÝðŽ4õrel8&Compare two expressions for equality. This corresponds to the SQL IS NOT DISTINCT FROM operator, and will equate null values as true. This differs from = which would return null#. This operator matches Haskell's É- operator. For an operator identical to SQL =, see ÷.örel82Test if two expressions are different (not equal).This corresponds to the SQL IS DISTINCT FROM operator, and will return false when comparing two null$ values. This differs from ordinary <> which would return null'. This operator is closer to Haskell's Ê- operator. For an operator identical to SQL <>, see ø.÷rel8µTest if two expressions are equal. This operator is usually the best choice when forming join conditions, as PostgreSQL has a much harder time optimizing a join that has multiple Ë conditions.This corresponds to the SQL =+ operator, though it will always return a Ì.ørel8'Test if two expressions are different. This corresponds to the SQL <>+ operator, though it will always return a Ì.ùrel8 Like the SQL IN8 operator, but implemented by folding over a list with õ and k.öøõ÷ùõ‡ö‡÷‡ø‡‹None%(-1=ÂÃÄÍÚÛÝðù�Åúrel8 The class of D“s that can be compared for equality. Equality on tables is defined by equality of all columns all columns, so this class means "all columns in a D have an instance of 0".ürel8 Compare two Dÿs for equality. This corresponds to comparing all columns inside each table for equality, and combining all comparisons with AND.ýrel8 Test if two D‚s are different. This corresponds to comparing all columns inside each table for inequality, and combining all comparisons with OR.Œþýüúûü‡ý‡�None%(1=ÂÃÄÍÚÛÝðù”jÿrel8 The class of Table�s that can be ordered. Ordering on tables is defined by their lexicographic ordering of all columns, so this class means "all columns in a Table have an instance of 3".�rel8 Test if one Table sorts before another. Corresponds to comparing all columns with Í.‚rel8 Test if one TableÓ sorts before, or is equal to, another. Corresponds to comparing all columns with Î.ƒrel8 Test if one TableÁ sorts after another. Corresponds to comparing all columns with Ï.„rel8 Test if one TableÁ sorts after another. Corresponds to comparing all columns with Ð.…rel8 Given two Table0s, return the table that sorts before the other.†rel8 Given two Table/s, return the table that sorts after the other.އ�‚ƒ„†…ÿ€�‡‚‡ƒ‡„‡�None '1ÍÛÝð– ˆrel8 Construct an  for a TableÙ by sorting all columns into ascending orders (any nullable columns will be sorted with  NULLS FIRST).‰rel8 Construct an  for a TableÚ by sorting all columns into descending orders (any nullable columns will be sorted with  NULLS LAST).ˆ‰�NoneÙËrel8ÎCombine the results of two queries of the same type, collapsing duplicates.  union a b" is the same as the SQL statement  a UNION b.Œrel8ÌCombine the results of two queries of the same type, retaining duplicates.  unionAll a b" is the same as the SQL statement  a UNION ALL b.�rel8>Find the intersection of two queries, collapsing duplicates. intersect a b" is the same as the SQL statement  a INTERSECT b.Žrel8=Find the intersection of two queries, retaining duplicates. intersectAll a b" is the same as the SQL statement a INTERSECT ALL b.�rel8:Find the difference of two queries, collapsing duplicates  except a b# is the same as the SQL statement  a EXCEPT b.�rel8;Find the difference of two queries, retaining duplicates.  exceptAll a b# is the same as the SQL statement a EXCEPT ALL b.���Ž‹Œ‘NoneÃù›Šrel8The Query monad allows you to compose a SELECT7 query. This monad has semantics similar to the list ([]) monad.Ñrel8Ò = ‘ [].Órel8² = Œ.Ôrel8 = ‘ [].Õrel8� = Œ.ŠÖ’None)*1ù›2רÙÚÛÜÝ“None›�’rel8#Order the rows returned by a query.’”NoneÞU“rel8“ takes a ŠÜ and fully evaluates it and caches the results thereof, and passes to a continuation a new Šò that simply looks up these cached results. It's usually best not to use this and to let the Postgres optimizer decide for itself what's best, but if you know what you're doing this can sometimes help to nudge it in a particular direction.“1 is currently implemented in terms of Postgres'  9https://www.postgresql.org/docs/current/queries-with.html@WITH syntax, specifically the WITH _ AS MATERIALIZED (_)4 form introduced in PostgreSQL 12. This means that “/ can only be used with PostgreSQL 12 or newer.“•NoneÃ¥“”rel8”À allows the construction of recursive queries, using Postgres'  Ðhttps://www.postgresql.org/docs/current/queries-with.html#QUERIES-WITH-RECURSIVEWITH RECURSIVE( under the hood. The first argument to ”à is what the Postgres documentation refers to as the "non-recursive term" and the second argument is the "recursive term", which is defined in terms of the result of the "non-recursive term". ” uses  UNION ALL3 to combine the recursive and non-recursive terms.Denotionally, ” s f is the smallest set of rows r such that r == s `– ` (r >>= f) Operationally, ” s f" takes each row in an initial set s and supplies it to fƒ, resulting in a new generation of rows which are added to the result set. Each row from this new generation is then fed back to fÉ, and this process is repeated until a generation comes along for which f+ returns an empty set for each row therein.•rel8• is like ” but uses UNION instead of  UNION ALL3 to combine the recursive and non-recursive terms.Denotationally, • s f is the smallest set of rows r such that r == s `~ ` (r >>= f) Operationally, • s f takes each distinct row in an initial set s and supplies it to f?, resulting in a new generation of rows. Any rows returned by fÙ that already exist in the result set are not considered part of this new generation by • (in contrast to ”â). This new generation is then added to the result set, and each row therein is then fed back to fÉ, and this process is repeated until a generation comes along for which f= returns no rows that don't already exist in the result set.”•—None¦²–rel8limit n select at most n rows from a query. limit n is equivalent to the SQL LIMIT n.—rel8offset n drops the first n rows from a query. offset n is equivalent to the SQL OFFSET n.–—˜NoneçØrel8˜ä takes a variable name, some expressions, and binds each of them to a new variable in the SQL. The aÀ returned consists only of these variables. It's essentially a let" binding for Postgres expressions.Þ˜™Noneèc™rel8ÐSelect each row from a function that returns a relation. This is equivalent to FROM function(input).™šNoneª)šrel8 filter f x will be a zero-row query when f x is False, and will return x unchanged when f x is True. This is similar to ›œÚ, but as the predicate is separate from the argument, it is easy to use in a pipeline of Š transformations.›rel8-Drop any rows that don't match a predicate.  where_ expr is equivalent to the SQL  WHERE expr.š›�NoneÃÕ«œrel8œÔ takes expressions that could potentially have side effects and "runs" them in the ŠÐ monad. The returned expressions have no side effects and can safely be reused.œžNoneë“�rel8?Select each row from a table definition. This is equivalent to  FROM table.�ŸNone1®Xžrel8+Checks if a query returns at least one row.Ÿrel8 Query b yields no rows.¤rel8Like without$, but with a custom membership test. žßŸ¡¢£¤ None°ä¥rel8=Select all distinct rows from a query, removing duplicates.  distinct q% is equivalent to the SQL statement SELECT DISTINCT q.¦rel8ÌSelect all distinct rows from a query, where rows are equivalent according to a projection. If multiple rows have the same projection, it is unspecified which row will be returned. If this matters, use §.§rel8¼Select all distinct rows from a query, where rows are equivalent according to a projection. If there are multiple rows with the same projection, the first row according to the specified  will be returned.¥¦§None"ÃÍÛ¶K ¨rel8Cast 6 types to 7À types. For example, this can be useful if you need to turn an  Expr Int32 into an  Expr Double.©rel8Cast 7 types to 54 types. For example, this can be useful to convert  Expr Float to  Expr Double.ªrel8Round a 5 to a 6, by rounding to the nearest larger integer.Corresponds to the  ceiling() function.«rel8/Emulates the behaviour of the Haskell function ¡¢ in PostgreSQL.¬rel8/Emulates the behaviour of the Haskell function ¡£ in PostgreSQL.­rel8 Simultaneous « and ¬.®rel8.Perform integral division. Corresponds to the div()7 function in PostgreSQL, which behaves like Haskell's ¡¤ rather than ¡¢.¯rel8Corresponds to the mod()7 function in PostgreSQL, which behaves like Haskell's ¡¥ rather than ¡£.°rel8 Simultaneous ® and ¯.±rel8Round a  DFractional to a 6. by rounding to the nearest smaller integer. Corresponds to the floor() function.²rel8Round a 5 to a 6% by rounding to the nearest integer.Corresponds to the round() function.³rel8Round a 5 to a 62 by rounding to the nearest integer towards zero. ª«­±¨¬®°©¯²³ ¨©«¬­®¯°ª±²³¦Noneºôãrel8Corresponds to the SQL DEFAULT expression.This \> is unsafe for numerous reasons, and should be used with care: This \ only makes sense in an INSERT or UPDATE statement.ÄRel8 is not able to verify that a particular column actually has a DEFAULT value. Trying to use  unsafeDefault6 where there is no default will cause a runtime crashDEFAULTÅ values cannot be transformed. For example, the innocuous Rel8 code unsafeDefault + 1# will crash, despite type checking./Also note, PostgreSQL's syntax rules mean that DEFAULT can only appear in INSERT, expressions whose rows are specified using VALUES. This means that if the rows field of your M record doesn't look like  values [..], then  unsafeDefault won't work.ïGiven all these caveats, we suggest avoiding the use of default values where possible, instead being explicit. A common scenario where default values are used is with auto-incrementing identifier columns. In this case, we suggest using § instead.ã¨None)*1ÍÝùÆ£´rel8An ´$ takes a collection of rows of type aÄ, groups them, and transforms each group into a single row of type b). This corresponds to aggregators using GROUP BY0 in SQL. If given an empty collection of rows, ´Ñ will have no groups and will therefore also return an empty collection of rows.´ is a special form of ¶ parameterised by .µrel8An µ takes a ) producing a collection of rows of type a and transforms it into a ! producing a single row of type b. If the given Í produces an empty collection of rows, then the single row in the resulting Ë contains the identity values of the aggregation functions comprising the µ (i.e., 0 for ©, ª for «, etc.).µ is a special form of ¶ parameterised by .¶rel8¶5 is the most general form of "aggregator", of which µ and ´ are special cases. ¶1s are comprised of aggregation functions and/or GROUP BY clauses..Aggregation functions operating on individual K s such as © can be combined into µ's operating on larger types using the à, á and â interfaces. Working with á(s can sometimes be awkward so for every © we also provide a ¬ which bundles an ­®Ì. For complex aggregations, we recommend using these functions along with  ApplicativeDo, BlockArguments, OverloadedRecordDot and RecordWildCards: • data Input f = Input { orderId :: Column f OrderId , customerId :: Column f CustomerId , productId :: Column f ProductId , quantity :: Column f Int64 , price :: Column f Scientific } deriving (Generic, Rel8able) totalPrice :: Input Expr -> Expr Scientific totalPrice input = fromIntegral input.quantity * input.price data Result f = Result { customerId :: Column f CustomerId , totalOrders :: Column f Int64 , productsOrdered :: Column f Int64 , totalPrice :: Column f Scientific } deriving (Generic, Rel8able) allResults :: Query (Result Expr) allResults = aggregate do customerId <- groupByOn (.customerId) totalOrders <- countDistinctOn (.orderId) productsOrdered <- countDistinctOn (.productId) totalPrice <- sumOn totalPrice pure Result {..} do order <- each orderSchema orderLine <- each orderLineSchema where_ $ order.id ==. orderLine.orderId pure Input { orderId = order.id , customerId = order.customerId , productId = orderLine.productId , quantity = orderLine.quantity , price = orderLine.price } ·rel8· turns an µ into an ´.¸rel8ÅGiven a value to fall back on if given an empty collection of rows, ¸ turns an ´ into an µ.㸷䵶崯None'1ÂÃÄÅÆÍÚÛÝäðùÆñæçèéê°NoneÃÇ´¹rel8¹„ allows the use use of custom aggregation functions or PostgreSQL aggregation functions which are not otherwise supported by Rel8.¹º±NoneÂÃÄÅÆùÈD»rel8)The class of data types that support the  string_agg() aggregation function.»²None 1ÂÃÄÅÆÍÛùÈÕ¼rel8-The class of database types that support the sum() aggregation function.¼³None "%'1ÃÍÛÝðפ+½rel88Count the occurances of a single column. Corresponds to COUNT(a)¾rel8Applies ½. to the column selected by the given function.¿rel8ÍCount the number of distinct occurrences of a single column. Corresponds to COUNT(DISTINCT a)Àrel8Applies ¿. to the column selected by the given function.Árel8Corresponds to COUNT(*).Ârel85A count of the number of times a given expression is true.Ãrel8Applies Â. to the column selected by the given function.Ärel8Corresponds to bool_and.Årel8Applies Ä. to the column selected by the given function.Ærel8Corresponds to bool_or.Çrel8Applies Æ. to the column selected by the given function.Èrel8Produce an aggregation for Expr a using the max function.Érel8Applies È. to the column selected by the given function.Êrel8Produce an aggregation for Expr a using the min function.Ërel8Applies Ê. to the column selected by the given function.Ìrel8Corresponds to sum. Note that in SQL, sum% is type changing - for example the sum of integer returns a bigint½. Rel8 doesn't support this, and will add explicit casts back to the original input type. This can lead to overflows, and if you anticipate very large sums, you should upcast your input.Írel8Applies Ì. to the column selected by the given fucntion.Îrel8Î is a combination of ´ and Í.Ïrel8Corresponds to avg. Note that in SQL, avg& is type changing - for example, the avg of integer returns a numeric². Rel8 doesn't support this, and will add explicit casts back to the original input type. If you need a fractional result on an integral column, you should cast your input to ë or µ¶ before calling Ï.Ðrel8Applies Ï. to the column selected by the given fucntion.Ñrel8Corresponds to  string_agg().ìrel8Applies Ñ. to the column selected by the given function.Òrel8Corresponds to  mode() WITHIN GROUP (ORDER BY _).Órel8Applies Ò. to the column selected by the given function.Ôrel8Corresponds to ,percentile_disc(_) WITHIN GROUP (ORDER BY _).Õrel8Applies Ô. to the column selected by the given function.Örel8Corresponds to ,percentile_cont(_) WITHIN GROUP (ORDER BY _).×rel8Applies Ö/ to the column selected by the given function.Ørel8Corresponds to !rank(_) WITHIN GROUP (ORDER BY _).Ùrel8Corresponds to 'dense_rank(_) WITHIN GROUP (ORDER BY _).Úrel8Corresponds to )percent_rank(_) WITHIN GROUP (ORDER BY _).Ûrel8Corresponds to &cume_dist(_) WITHIN GROUP (ORDER BY _).írel8$Aggregate a value by grouping by it.îrel8Applies í. to the column selected by the given function.Ürel8%Collect expressions values as a list.Ýrel8Applies Ü. to the column selected by the given function.Þrel8/Collect expressions values as a non-empty list.ßrel8Applies Þ. to the column selected by the given function.àrel8%Concatenate lists into a single list.árel8Applies à. to the column selected by the given function.ârel89Concatenate non-empty lists into a single non-empty list.ãrel8Applies â. to the column selected by the given function.ärel8ä modifies an å° to consider only distinct values of each particular column. Note that this "distinction" only happens within each column individually, not across all columns simultaneously.0ãÄÅÏн¿À¾ÁÂÃäíîÛÙÚØÜÝàáÈÉÊËÒÓÞßâãÆÇÔÖ×ÕïðñòÑìÌÍηNone1>ÀÁÒùØ. óôõö÷øùúû¸None1<>ÀùØgüýþÿ€�¹None1<>ÀùØš‚ƒ„…ºNone'19ÀÂÃÄÅÆÍÚÛÝðùßp årel8 MaybeTable t is the table tå, but as the result of an outer join. If the outer join fails to match any rows, this is essentialy Nothing7, and if the outer join does match rows, this is like Justœ. Unfortunately, SQL makes it impossible to distinguish whether or not an outer join matched any rows based generally on the row contents - if you were to join a row entirely of nulls, you can't distinguish if you matched an all null row, or if the match failed. For this reason  MaybeTableã contains an extra field - a "nullTag" - to track whether or not the outer join produced any rows.ærel8 Check if a  MaybeTable is absent of any row. Like hi.çrel8 Check if a  MaybeTable contains a row. Like hj.èrel8Perform case analysis on a å. Like €.érel8The null table. Like Ç.êrel8Lift any table into å. Like †. Note you can also use ‡.ërel8h» for ås.ìrel8%Project a single expression out of a å+. You can think of this operator like the ˆ2 operator, but it also has the ability to return null.írel8 Construct a å in the ƒ, context. This can be useful if you have a å: that you are storing in a table and need to construct a  TableSchema.‰rel8Has the same behavior as the Monad instance for Maybe.Šrel8Has the same behavior as the  Applicative instance for Maybe . See also: ¼.írel83The name of the column to track whether a row is a ê or é.rel8Names of the columns in a.ìëçæê‹èíéŒå�Ž�쇽None1ÂÃÄÅÆÍÚÛÝðùät îrel8 NullTable t is the table t, but where all the columns in t have the possibility of being ¾. This is very similar to vÔ, except that it does not use an extra tag field, so it cannot distinguish between Nothing and  Just Nothing: if nested. In other words, if all of the columns of the t passed to  NullTable are already nullable, then  NullTable has no effect.ïrel8+Check if any of the non-nullable fields of a are ¾ under the î . Returns ª if a has no non-nullable fields.ðrel8The inverse of ï.ñrel8Like g.òrel8The null table. Like ¾.órel8Lift any table into î. Like ¿.ôrel8Assume that a î is non-null. Like À.õrel8 Construct a î in the ƒ, context. This can be useful if you have a î: that you are storing in a table and need to construct a  TableSchema.örel8 Convert a î to a å.÷rel8 Convert a å to a î. Note that if the underlying a9 has no non-nullable fields, this is a lossy conversion. ðïõòñóö÷ôî�ÁNone'1ÂÃÄÅÆÍÚÛÝðùèFørel8A  NonEmptyTable) value contains one or more instances of a. You construct  NonEmptyTables with  or  nonEmptyAgg.ùrel8%Project a single expression out of a ø.úrel8 Construct a  NonEmptyTable& from a non-empty list of expressions.ûrel8 Construct a ø in the ƒ, context. This can be useful if you have a ø: that you are storing in a table and need to construct a  TableSchema.ürel8Get the first element of a ø.ýrel8ý i as extracts a single element from as , returning à if iù is out of range. Note that although PostgreSQL array indexes are 1-based (by default), this function is always 0-based.þrel8Get the last element of a ø.ÿrel8Get the length of a øûrel81The names of the columns of elements of the list. ùüýþÿûúø‘ù‡ÄNone 1ÍÛùéG€rel8Nest a ’ list within a Rel8able.  HNonEmpty f a will produce a ø a in the Expr context, and a ’ a in the A context.€ÅNone'1ÂÃÄÅÆÍÚÛÝðùí�rel8A  ListTable* value contains zero or more instances of a. You construct  ListTables with Æ or Ç.‚rel8%Project a single expression out of a �.ƒrel8 Construct a  ListTable from a list of expressions.„rel8 Construct a � in the ƒ, context. This can be useful if you have a �: that you are storing in a table and need to construct a  TableSchema.…rel8Get the first element of a � (or à if empty).†rel8† i as extracts a single element from as , returning à if iù is out of range. Note that although PostgreSQL array indexes are 1-based (by default), this function is always 0-based.‡rel8Get the last element of a � (or à if empty).ˆrel8Get the length of a �„rel81The names of the columns of elements of the list. ‚…†‡ˆƒ„�“‚‡ÈNone '-ÃÍÛÝðöI ‰rel8ÜGroup equal tables together. This works by aggregating each column in the given table with  groupByExpr.àFor example, if we have a table of items, we could group the items by the order they belong to: ÙitemsByOrder :: Query (OrderId Expr, ListTable Expr (Item Expr)) itemsByOrder = aggregate do orderId <- groupByOn (.orderId) items <- listAgg pure (orderId, items) do each itemSchema Šrel8Applies ‰/ to the columns selected by the given function.‹rel8‹ allows an µ€ to filter out rows from the input query before considering them for aggregation. Note that because the predicate supplied to ‹ could return ª for every row, ‹ needs an µ as opposed to an ´Ë, so that it can return a default value in such a case. For a variant of ‹ that can work with ´s, see É.Œrel8ŒAggregate rows into a single row containing an array of all aggregated rows. This can be used to associate multiple rows with a single row, without changing the over cardinality of the query. This allows you to essentially return a tree-like structure from queries.ŸFor example, if we have a table of orders and each orders contains multiple items, we could aggregate the table of orders, pairing each order with its items: ¿ordersWithItems :: Query (Order Expr, ListTable Expr (Item Expr)) ordersWithItems = do order <- each orderSchema items <- aggregate listAgg (itemsFromOrder order) return (order, items) �rel8Applies Œ/ to the columns selected by the given function.Žrel8Like Œ6, but the result is guaranteed to be a non-empty list.�rel8Applies Ž/ to the columns selected by the given function.�rel8%Concatenate lists into a single list.‘rel8Applies �, to the list selected by the given function.’rel89Concatenate non-empty lists into a single non-empty list.“rel8Applies ’7 to the non-empty list selected by the given function.”rel8/Order the values within each aggregation in an µû using the given ordering. This is only relevant for aggregations that depend on the order they get their elements, like Ç and Ê. ‹‰ŠŒ��‘Ž�’“”ËNone 1ÍÛù÷4•rel8Nest a list within a Rel8able.  HList f a will produce a � a in the Expr context, and a [a] in the A context.•None"Ãø–rel8– a as tests whether a is an element of the list as.—rel8— a as tests whether a& is an element of the non-empty list as.–—›œ�ž—˜™š‘’…†‡ˆüýþÿ�ø�…›†œ‡�ˆž–øü—ý˜þ™ÿš—‘’–‡—‡ÌNoneÃù¥˜rel8 Filter a Š that might return null to a Š without any nulls.Corresponds to hÍ.™rel8 Filter a Š that might return  nullTable to a Š without any  nullTables.Corresponds to hÍ.˜™ÎNone 1ÍÛùúŽšrel8Nest a Null value within a Rel8able.  HNull f a will produce a î a in the Expr context, and a ‚ a in the A context.šÏNoneÃþx›rel8 A variant of ‹ that can be used with an ´ (upgrading it to an µ in the process). It returns é3 in the case where the predicate matches zero rows.œrel8œ upgrades an ´ into an µ by having it return é4 when aggregating over an empty collection of rows.�rel8Lift an µ to operate on a å. If the input query has ê i!s, they are folded into a single aÅ by the given aggregator ”@ in the case where the input query is all és, the µ 's fallback a is returned.žrel8Lift an ´ to operate on a å. If the input query has ê i!s, they are folded into a single ê aÆ by the given aggregator ”@ in the case where the input query is all é s, a single é row is returned.Ÿrel8#Lift an aggregator to operate on a å.  nothingTables and  justTables are grouped separately.�žŸ›œÐNone'19ÀÂÃÄÅÆÍÕÚÛÝðù› rel8TheseTable a b0 is a Rel8 table that contains either the table a , the table b, or both tables a and b. You can construct  TheseTable s using ©, ª and «.  TheseTable+s can be eliminated/pattern matched using ¬. TheseTable( is operationally the same as Haskell's ”& type, but adapted to work with Rel8.¡rel8 Test if a   was constructed with ©.Corresponds to ÑÒ.¢rel8 Test if a   was constructed with ª.Corresponds to ÑÓ.£rel8 Test if a   was constructed with «.Corresponds to ÑÔ.¤rel8 Test if the a side of TheseTable a b is present.Corresponds to ÑÕ.¥rel8 Test if the b table of TheseTable a b is present.Corresponds to ÑÖ.¦rel8Attempt to project out the a table of a TheseTable a b.Corresponds to Ñ×.§rel8Attempt to project out the b table of a TheseTable a b.Corresponds to ÑØ.¨rel8 Construct a  TheseTable from two ås.©rel8 Construct a  TheseTable. Corresponds to •.ªrel8 Construct a  TheseTable. Corresponds to –.«rel8 Construct a  TheseTable. Corresponds to ”.¬rel8Pattern match on a  . Corresponds to these.­rel8Lift an µ to operate on a  . If the input query has © a!s, they are folded into a single cÅ by the given aggregator ”@ in the case where the input query is all ªs or «s, the µ 's fallback c is returned.®rel8Lift an ´ to operate on a  . If the input query has © a!s, they are folded into a single Ù cÆ by the given aggregator ”@ in the case where the input query is all ªs or « s, a single é row is returned.¯rel8Lift an µ to operate on a  . If the input query has ª b!s, they are folded into a single cÅ by the given aggregator ”@ in the case where the input query is all ©s or «s, the µ 's fallback c is returned.°rel8Lift an ´ to operate on a  . If the input query has ª b!s, they are folded into a single Ù cÆ by the given aggregator ”@ in the case where the input query is all ©s or « s, a single é row is returned.±rel8Lift an µ to operate on a  ThoseTable. If the input query has « a b!s, they are folded into a single cÅ by the given aggregator ”@ in the case where the input query is all ©s or ªs, the µ 's fallback c is returned.²rel8Lift an ´ to operate on a  . If the input query has « a b!s, they are folded into a single Ù cÆ by the given aggregator ”@ in the case where the input query is all ©s or ª s, a single é row is returned.³rel8Lift an µ to operate on a  . If the input query has © as or « a _s, the as are folded into a single cÅ by the given aggregator ”@ in the case where the input query is all ªs, the µ 's fallback c is returned.´rel8Lift an ´ to operate on an  . If the input query has © as or « a _s, the as are folded into a single Ù cÅ by the given aggregator ”@ in the case where the input query is all ª s, a single é row is returned.µrel8Lift an µ to operate on a  . If the input query has ª bs or « _ bs, the bs are folded into a single cÅ by the given aggregator ”@ in the case where the input query is all ©s, the µ 's fallback c is returned.¶rel8Lift an ´ to operate on an  . If the input query has ª bs or « _ bs, the bs are folded into a single Ù cÅ by the given aggregator ”@ in the case where the input query is all © s, a single é row is returned.·rel8(Lift a pair aggregators to operate on a  . ©s, ªs are «s are grouped separately.¸rel8 Construct a   in the ƒ, context. This can be useful if you have a  : that you are storing in a table and need to construct a  TableSchema.¸rel84The name of the column to track the presence of the a table.rel84The name of the column to track the presence of the b table.rel8Names of the columns in the a table.rel8Names of the columns in the b table.³´¯°µ¶·­®±²¨¤¥¢¡£¦§¸ª¬©« —˜™ÚNone 1ÍÛùÀ¹rel8Nest an ” value within a Rel8able.  HThese f a b will produce a   a b in the Expr context, and a ” a b in the A context.¹ÛNone')*äìºrel8ÝConvert a query that might return zero rows to a query that always returns at least one row.!To speak in more concrete terms, º is most useful to write  LEFT JOINs.»rel8 Filter out å/s, returning only the tables that are not-null.3This operation can be used to "undo" the effect of º), which operationally is like turning a  LEFT JOIN back into a full JOIN*. You can think of this as analogous to hÍ.¼rel8ãExtend an optional query with another query. This is useful if you want to step through multiple  LEFT JOINs. Note that traverseMaybeTable takes a  a -> Query bã function, which means you also have the ability to "expand" one row into multiple rows. If the  a -> Query bî function returns no rows, then the resulting query will also have no rows. However, regardless of the given  a -> Query b function, if the input is  nothingTable", you will always get exactly one  nothingTable back.»º¼ÜNoneÃÝ(½rel8 Apply an µ to all rows returned by a Š . If the Š‚ is empty, then a single "fallback" row is returned, composed of the identity elements of the constituent aggregation functions.¾rel8 Apply an Ý to all rows returned by a Š . If the Š' is empty, then zero rows are returned.¿rel8ÐCount the number of rows returned by a query. Note that this is different from  countStar-, as even if the given query yields no rows,  countRows will return 0.½¾š¿ÞNone%&')*9ÀÁÃØÝäðù JÀrel8ÀÕ represents a single PostgreSQL statement. Most commonly, this is constructed using ß, à, á or â.However, in addition to SELECT, INSERT, UPDATE and DELETEÊ, PostgreSQL also supports compositions thereof via its statement-level WITHî syntax (with some caveats). Each such "sub-statement" can reference the results of previous sub-statements. À provides a ›/ instance that captures this "binding" pattern.!The caveat with this is that the  Ðhttps://www.postgresql.org/docs/current/queries-with.html#QUERIES-WITH-MODIFYINGÍside-effects of these sub-statements are not visible to other sub-statements>; only the explicit results of previous sub-statements (from SELECTs or  RETURNING+ clauses) are visible. So, for example, an INSERT) into a table followed immediately by a SELECTê therefrom will not return the inserted rows. However, it is possible to return the inserted rows using  RETURNING, –ing this with the result of a SELECT6 from the same table will produce the desired result.ˆAn example of where this can be useful is if you want to delete rows from a table and simultaneously log their deletion in a log table. ãdeleteFoo :: (Foo Expr -> Expr Bool) -> Statement () deleteFoo predicate = do foos <- delete Delete { from = fooSchema , using = pure () , deleteWhere = \_ -> predicate , returning = Returning id } insert Insert { into = deletedFooSchema , rows = do Foo {..} <- foos let deletedAt = ãÛ pure DeletedFoo {..} , onConflict = Abort , returning = NoReturning } œ�žÀäNone 19:;ÀÃÝðù ­Árel8Build a SELECT À.Ÿ ¡Á¢£¤¥åNone" Þ¦§æNoneÃ!WÂrel8 Convert a Š to a ¨ containing a SELECT statement.ÂçNone'*Ãrel8 Convert a À to a runnable èé7, disregarding the results of that statement (if any).  run_ :: Rel8.À exprs -> Hasql.èé () () Ärel8 Convert a À to a runnable èéÀ, returning the number of rows affected by that statement (for às, ás or Rel8.delete's with ê).  runN :: Rel8.À () -> Hasql.èé () © Årel8 Convert a À to a runnable èé’, processing the result of the statement as a single row. If the statement returns a number of rows other than 1, a runtime exception is thrown. run1 :: “ exprs a => Rel8.À (Š exprs) -> Hasql.èé () a Ærel8 Convert a À to a runnable èé-, processing the result of the statement as Ùë a single row. If the statement returns a number of rows other than 0 or 1, a runtime exception is thrown.  runMaybe :: “ exprs a => Rel8.À (Š exprs) -> Hasql.èé () (Ù a) Çrel8 Convert a À to a runnable èé<, processing the result of the statement as a list of rows. run :: “ exprs a => Rel8.À (Š exprs) -> Hasql.èé () [a] Èrel8 Convert a À to a runnable èé/, processing the result of the statement as a Ü of rows.  runVector :: “ exprs a => Rel8.À (Š exprs) -> Hasql.èé () (Ü a) ÇÅÆÄÈÃëNone ')*1ÃØÝäðòù(èÉrel8M, ì and í all support an optional  RETURNING clause.Êrel8No  RETURNING clauseËrel8ÉÛ allows you to project out of the affected rows, which can be useful if you want to log exactly which rows were deleted, or to view a generated id (for example, if using a column with an autoincrementing counter via §).ª«ÉÊËîNone %&')*Ãéòù*ßÌrel8The constituent parts of an UPDATE statement.Îrel8What to return from the UPDATE statement.Ïrel8 Which rows to select for update.Ðrel8 How to update each selected row.Ñrel8FROMã clause ”@ this can be used to join against other tables, and its results can be referenced in the SET and WHERE clauses.Òrel8Which table to update.Órel8 Build an UPDATE À. ¬ÓÌÍÑÎÐÒÏïNone'-ÃÝð,ÔÔrel8Given a ð function that converts a À to a èé , return a ð%-like function which instead takes a  parameterized À and converts it to a  preparable èé.The parameters i¶ are sent to the database directly via PostgreSQL's binary format. For large amounts of data this can be significantly more efficient than embedding the values in the statement with _.­ÔñNone %&')*Ãéòù.–Õrel8The constituent parts of a SQL INSERT statement.×rel8)What information to return on completion.Ørel8ÉWhat to do if the inserted rows conflict with data already in the table.Ùrel8:The rows to insert. This can be an arbitrary query ”@ use ò insert a static list of rows.Úrel8Which table to insert into.Ûrel8 Build an INSERT À. Û®¯ÕÖÚØ×ÙóNoneÃ0ÇÜrel8Given a   and Š,  createView runs a  CREATE VIEW„ statement that will save the given query as a view. This can be useful if you want to share Rel8 queries with other applications.Ýrel8Given a   and Š, createOrReplaceView runs a CREATE OR REPLACE VIEW· statement that will save the given query as a view, replacing the current view definition if it exists and adheres to the restrictions in place for replacing a view in PostgreSQL.ÝÜôNone %&')*Ãéòù2ŠÞrel8The constituent parts of a DELETE statement.àrel8What to return from the DELETE statement.árel8+Which rows should be selected for deletion.ârel8USINGã clause ”@ this can be used to join against other tables, and its results can be referenced in the WHERE clauseãrel8Which table to delete from.ärel8Build a DELETE À.ä°ÞßáãàâõNoneÃ4Wårel8 Convert a Þ to a ¨ containing a DELETE statement.ærel8 Convert an Õ to a ¨ containing an INSERT statement.çrel8 Convert an Ì to a ¨ containing an UPDATE statement.èrel8 Convert a À to a ¨ containing an SQL statement.érel8Convert a parameterized À to a ¨ containing an SQL statement.åæéèçöNone')*Ã;êrel8 Aggregate a Š into a �Æ. If the supplied query returns 0 rows, this function will produce a Š, that returns one row containing the empty  ListTable. If the supplied Query does return rows, many& will return exactly one row, with a  ListTable collecting all returned rows.many is analogous to ÷Æ from Control.Applicative.ërel8 Aggregate a Š into a øÆ. If the supplied query returns 0 rows, this function will produce a Š- that is empty - that is, will produce zero  NonEmptyTables. If the supplied Query does return rows, some% will return exactly one row, with a  NonEmptyTable collecting all returned rows.some is analogous to ÷ from Control.Applicative.ìrel8 A version of ê# specialised to single expressions.írel8 A version of ê# specialised to single expressions.îrel8 Expand a � into a Š:, where each row in the query is an element of the given  ListTable. catListTable is an inverse to ê.ïrel8 Expand a ø into a Š:, where each row in the query is an element of the given  NonEmptyTable.catNonEmptyTable is an inverse to ë.ðrel81Expand an expression that contains a list into a Š?, where each row in the query is an element of the given list.catList is an inverse to ì.ñrel8;Expand an expression that contains a non-empty list into a Š?, where each row in the query is an element of the given list. catNonEmpty is an inverse to í.ðîñïêìëíøNone 1ÍÛù;úòrel8Nest a ‚ value within a Rel8able.  HMaybe f a will produce a å a in the Expr context, and a ‚ a in the A context.òùNone1<>Àù<#±²³´µúNone'149ÀÂÃÄÅÆÍÚÛÝäðùE órel8An EitherTable a b0 is a Rel8 table that contains either the table a or the table b. You can construct an  EitherTable using ÷ and ø$, and eliminate/pattern match using ö.An  EitherTable( is operationally the same as Haskell's ¶& type, but adapted to work with Rel8.ôrel8 Test if an ó is a ÷.õrel8 Test if an ó is a ø.örel8Pattern match/eliminate an ó , by providing mappings from a ÷ and ø.÷rel8Construct a left ó. Like ·.ørel8Construct a right ó. Like ¸.ùrel8Lift an µ to operate on an ó. If the input query has ÷ a!s, they are folded into a single cÅ by the given aggregator ”@ in the case where the input query is all øs, the µ 's fallback c is returned.úrel8Lift an ´ to operate on an ó. If the input query has ÷ a!s, they are folded into a single Ù cÆ by the given aggregator ”@ in the case where the input query is all ø s, a single  nothingTable row is returned.ûrel8Lift an µ to operate on an ó. If the input query has ø b!s, they are folded into a single cÅ by the given aggregator ”@ in the case where the input query is all øs, the µ 's fallback c is returned.ürel8Lift an ´ to operate on an ó. If the input query has ø b!s, they are folded into a single Ù cÆ by the given aggregator ”@ in the case where the input query is all ÷ s, a single  nothingTable row is returned.ýrel8)Lift a pair aggregators to operate on an ó.  leftTables and  rightTables are grouped separately.þrel8 Construct a ó in the ƒ, context. This can be useful if you have a ó: that you are storing in a table and need to construct a  TableSchema.þrel83The name of the column to track whether a row is a ÷ or ø.rel8Names of the columns in the a table.rel8Names of the columns in the b table.ýùúûüöôõ÷þøó¹º»¼ûNoneÃG½ÿrel8Filter ós, keeping only  leftTables.€rel8Filter ós, keeping only  rightTables.�rel8bitraverseEitherTable f g x will pass all  leftTable s through f and all  rightTable s through g). The results are then lifted back into  leftTable and  rightTable#, respectively. This is similar to  bitraverse for ¶. For example,:{ select do: x <- values (map lit [ Left True, Right (42 :: Int32) ])Ë bitraverseEitherTable (\y -> values [y, not_ y]) (\y -> pure (y * 100)) x:} [ Left True , Left False , Right 4200]�ÿ€üNone 1ÍÛùH±‚rel8Nest an ¶ value within a Rel8able.  HEither f a b will produce a ó a b in the Expr context, and a ¶ a b in the A context.‚ýNone)*ÃI ƒrel8Corresponds to a FULL OUTER JOIN between two queries. ƒŽ„ІˆŒ…‹‡‰�NoneÃÕÝùk]!�rel8A � k a is like a Š a', except that each row also has a key k in addition to the value a. �)s can be composed monadically just like Š*s, but the resulting join is more like a  NATURAL JOIN$ (based on the common key column(s) k ) than the  CROSS JOIN given by Š.Another way to think of � k a is as analogous to Map k a in the same way Š a is analogous to [a]'. However, there's nothing stopping a � from containing multiple rows with the same key, so technically Map k (NonEmpty a) is more accurate.�s can be created from Šs with � and ’ and converted back to Šs with ” and ‘6 (though note the caveats that come with the latter).�rel8Any Š of key-value pairs (k, a) can be a � k a.‘rel8 Convert a � k a back into a Š of key-value pairs.Note that the result of a ‘1 is undefined (will always return zero rows) on �s constructed with ’ or ‡ . So while toQuery . fromQuery is always id, fromQuery . toQuery is not.)A safer, more predictable alternative to ‘ is to use ” with an explicit set of keys: ;do k <- keys a <- lookup k tabulation pure (k, a) 7Having said that, in practice, most legitimate uses of � will have a well-defined ‘•. It would be possible in theory to encode the necessary invariants at the type level using an indexed monad, but we would lose the ability to use do0-notation, which is the main benefit of having � as a monad in the first place.In particular, ‘ t is well-defined for any � t defined as t = fromQuery _. ‘ t is also well-defined for any � t defined as  t = t' >>= _ or  t = t' *> _ where ‘ t'Ù is well-defined. There are other valid permutations too. Generally, anything that uses �/ at some point, unless wrapped in a top-level ž or Ÿ, will have a well-defined ‘.’rel8A Š a can be treated as a � k a where the given a% values exist at every possible key k.“rel8Run a Kleisli arrow in the the Š monad "through" a �. Useful for þing a �. þ ((>=. 30) . userAge) `through' usersById ”rel8” k t! returns the value(s) at the key k in the tabulation t.•rel8• produces a "magic" �< whereby the values within each group of keys in the given �Ë is aggregated according to the given aggregator, and every other possible key contains a single "fallback" row is returned, composed of the identity elements of the constituent aggregation functions.–rel8–- aggregates the values within each key of a �. There is an implicit GROUP BY on all the key columns.—rel8— ensures a �à has at most one value for each key, i.e., it drops duplicates. In general it keeps only the "first" value it encounters for each key, but note that "first" is undefined unless you first call ˜.˜rel8˜ orders the values of a �à within their respective keys. This specifies a defined order for —6. It also defines the order of the lists produced by › and œ.™rel8™7 returns a count of how many entries are in the given � at each key.The resulting � is "magic" in that the value 08 exists at every possible key that wasn't in the given �.šrel8š produces a "magic" �" whereby each entry in the given � is wrapped in Ù2, and every other possible key contains a single ÿ.This is used to implement £.›rel8›è aggregates each entry with a particular key into a single entry with all of the values contained in a �.˜ can be used to give this � a defined order.The resulting � is "magic" in that the value 'Rel8.listTable []'8 exists at every possible key that wasn't in the given �.œrel8œè aggregates each entry with a particular key into a single entry with all of the values contained in a ø.˜ can be used to give this ø a defined order.�rel8� produces a "magic" � which contains the value € at each key in the given �, and the value ª at every other possible key.žrel8ž produces a � where a single ()9 row exists for every key that was present in the given �.This is used to implement ¨.Ÿrel8Ÿ produces a � where a single ()> row exists at every possible key that absent from the given �.This is used to implement ©. rel8 Performs a NATURAL FULL OUTER JOIN! based on the common key columns. Analogous to �‚.¡rel8 Performs a NATURAL FULL OUTER JOIN! based on the common key columns. Analogous to �ƒ.¢rel8 Performs a NATURAL LEFT OUTER JOIN! based on the common key columns. Analogous to �„./Note that you can achieve the same effect with š and the à instance for �, i.e., this is just /\left right -> liftA2 (,) left (optional right). You can also use do -notation.£rel8 Performs a NATURAL LEFT OUTER JOIN! based on the common key columns. Analogous to �…./Note that you can achieve the same effect with š and the à instance for �, i.e., this is just /\f left right -> liftA2 f left (optional right). You can also use do -notation.¤rel8 Performs a NATURAL RIGHT OUTER JOIN! based on the common key columns. Analogous to �†./Note that you can achieve the same effect with š and the à instance for �, i.e., this is just 6\left right -> liftA2 (flip (,)) right (optional left). You can also use do -notation.¥rel8 Performs a NATURAL RIGHT OUTER JOIN! based on the common key columns. Analogous to �‡./Note that you can achieve the same effect with š and the à instance for �, i.e., this is just 6\f left right -> liftA2 (flip f) right (optional left). You can also use do -notation.¦rel8 Performs a NATURAL INNER JOIN! based on the common key columns. Analagous to �ˆ.3Note that you can achieve the same effect with the à instance of �, i.e., this is just  'liftA2 (,)'. You can also use do -notation.§rel8 Performs a NATURAL INNER JOIN! based on the common key columns. Analagous to �‰.3Note that you can achieve the same effect with the à instance of �, i.e., this is just ƒ. You can also use do -notation.¨rel8 Performs a  Øhttps://en.wikipedia.org/wiki/Relational_algebra#Semijoin_%28%E2%8B%89%29%28%E2%8B%8A%29NATURAL SEMI JOIN" based on the common key columns.„The result is a subset of the left tabulation where only entries which have a corresponding entry in the right tabulation are kept.0Note that you can achieve a similar effect with ž and the à instance of �, i.e., this is just $\left right -> left <* present right. You can also use do -notation.©rel8 Performs a  Éhttps://en.wikipedia.org/wiki/Relational_algebra#Antijoin_%28%E2%96%B7%29NATURAL ANTI JOIN" based on the common key columns.‹The result is a subset of the left tabulation where only entries which do not have a corresponding entry in the right tabulation are kept.0Note that you can achieve a similar effect with Ÿ and the à instance of �, i.e., this is just #\left right -> left <* absent right. You can also use do -notation.ªrel8Š‹ for �s.½rel8�s can be produced with either � or ’?, and in some cases we might want to treat these differently. ½ uses · to determine which type of � we have.¯rel8If � k a is Map k (NonEmpty a), then (<>) is unionWith (liftA2 (<>)).±rel8If � k a is Map k (NonEmpty a), then ( |:) is unionWith (<>).´rel8 pure = ’ . pureµrel8If � k a is Map k (NonEmpty a), then ( .) is intersectionWith (liftA2 ( *))Ÿ•– ¡™©—��¢£’”›ªš˜ž¤¥¨œ“‘¦§���‘’“”•–—˜ª™š›œ�žŸ ¡¢£¤¥¦§¨©“Œ�None1ÂÃÄÅÆÍØÚÛÝäðùl¾¿ÀÁÂÃŽNone1ÂÃÄÅÆÍØÚÛÝðùl]ÄÅÆÇÈ�None /01=ÂÃÄÅÆÍÚÛÝäðõùq|ºrel8,This type class allows you to define custom DÚs using higher-kinded data types. Higher-kinded data types are data types of the pattern: ¨data MyType f = MyType { field1 :: Column f T1 OR HK1 f , field2 :: Column f T2 OR HK2 f , ... , fieldN :: Column f Tn OR HKn f } where Tn is any Haskell type, and HKn is any higher-kinded type.ãThat is, higher-kinded data are records where all fields in the record are all either of the type  Column f T (for any T)), or are themselves higher-kinded data: Nested Ùdata Nested f = Nested { nested1 :: MyType f , nested2 :: MyType f } The Rel8ableã type class is used to give us a special mapping operation that lets us change the type parameter f.  Supplying Rel8able instancesëThis type class should be derived generically for all table types in your project. To do this, enable the DeriveAnyClass and  DeriveGeneric language extensions: Ž{-# LANGUAGE DeriveAnyClass, DeriveGeneric #-} data MyType f = MyType { fieldA :: Column f T } deriving ( GHC.Generics.Generic, Rel8able ) »rel8 The kind of º types�É‘Ê’Ë“Ì ÍλºÏÐÑÒÓÔÕÖ×”None-1ÂÃÄÅÆÍÕØÚÛÝðùqëØÙÚÛÜÝÞßàáâãäåæçèÍ•None'(/1ÃÍÚÛÝðùrF éêëìíîïðñòó–None1ÂÃÄÅÆÍØÚÛÝðùr›ÂÃôÄÅ¿õ¾ö½Á÷øÀ¼—None1ÍÛùrâÆ˜None 1ÂÃÄÅÆÍØÛÝðùs"ÍÎùÏÐÌúûËÊüÉýÈÇ™None1ÂÄÅÆÍÚÛÝðùsyšNone"%'()*-1ÃÝäðùw¨Ñrel8Ñà is used to associate composite type metadata with a Haskell type.Òrel83The names of all fields in the composite type that a maps to.Órel8$The name of the composite type that a maps to.Ôrel8‹A deriving-via helper type for column types that store a Haskell product type in a single Postgres column using a Postgres composite type.ÛNote that this must map to a specific extant type in your database's schema (created with  CREATE TYPE). Use Ñé to specify the name of this Postgres type and the names of the individual fields (for projecting with ×).Örel8 Collapse a Á" into a PostgreSQL composite type.Áé values are represented in queries by having a column for each field in the corresponding Haskell type. Öï collapses these columns into a single column expression, by combining them into a PostgreSQL composite type.×rel8Expand a composite type into a Á.× is the inverse of Ö.Ö×ÔÕÑÒÓ›None1ÍÛùwߨœNoneÀÁÃÒÝðù|MÙrel8„In PostgreSQL, window functions must specify the "window" or "partition" over which they operate. The syntax for this looks like: *SUM(salary) OVER (PARTITION BY department). The Rel8 type Ù) represents everything that comes after OVER.Ù is a �, so Ús created with Ü and  orderWindowBy can be combined using ².Úrel8ÚÆ is an applicative functor that represents expressions that contain  Ý (salary >$< ) Ürel8øRestricts a window function to operate only the group of rows that share the same value(s) for the given expression(s).Ýrel8ƒControls the order in which rows are processed by window functions. This does not need to match the ordering of the overall query.ÝÛÜÙÚþÛŒ�None~YÞrel8Þ2 runs a query composed of expressions containing  80 !$#%"-./*+,fg4567213YZ[de»¼ÙÚÚ()*+,-./YZ[ÔÕÑÒÓÖ×=>9:;ÀÂÃÄÒØÝäéðüœ‡òrel8ò< is used to allow the collection of a variety of different  TableSchemas under a single type, like: ¤userTable :: TableSchema (User Name) orderTable :: TableSchema (Order Name) tables :: [SomeTableSchema] tables = [SomeTableSchema userTable, SomeTable orderTable] This is used by  schemaErrors� to conveniently group every table an application relies on for typechecking the postgresql schemas together in a single batch.ôrel8ô£ shows an example CREATE TABLE statement for the table. This does not show relationships like primary or foreign keys, but can still be useful to see what types rel8( will expect of the underlying database.êIn the event that multiple columns have the same name, this will fail silently. To handle that case, see õõrel8õÏ shows an example CREATE TABLE statement for the table. This does not show relationships like primary or foreign keys, but can still be useful to see what types rel8 will expect of the underlying database.ýIn the event that multiple columns have the same name, this will return a map of names to the labels identifying the column.‰ rel8 pShowTable¥ is a helper function which takes a grid of text and prints it as a table, with padding so that cells are lined in columns, and a bordered header for the first rowörel8öÕ checks whether the provided schemas have the correct PostgreSQL column names and types to allow reading and writing from their equivalent Haskell types, returning a list of errors if that is not the case. The function does not crash on encountering a bug, instead leaving it to the caller to decide how to respond. A schema is valid if: )for every existing field, the types match3all non-nullable columns are present in the hs type1no nonexistent columns are present in the hs type5no two columns in the same schema share the same nameùIt's still possible for a valid schema to allow invalid data, for instance, if using an ADT, which can introduce restrictions on which values are allowed for the column representing the tag, and introduce restrictions on which columns are non-null depending on the value of the tag. However, if the schema is valid rel8 shouldn't be able to write invalid data to the table.éHowever, it is possible for migrations to cause valid data to become invalid in ways not detectable by this function, if the migration code changes the schema correctly but doesn't handle the value-level constraints correctly. So it is a good idea to both read from the tables and check the schema for errors in a transaction during the migration. The former will catch value-level bugs, while the latter will help ensure the schema is set up correctly to be able to insert new data.ÃThis function does nothing to check that the conflict target of an Upsert? are valid for the schema, nor can it prevent invalid uses of  unsafeDefaultÀ. However, it should be enough to catch the most likely errors.õöôòóöòóôõŠ ¥ ¦ §¨©ª«¬­­­®­¯°°°±°¯&²&²&²³&²´&µ&¶'·'·'·¸'·³'·´(¹(¹(¹º(¹»(¹¯)¼)¼)¼½)¼¾)¼¿)¼À)Á)Â0*0Ã131313Ä2Å2Å2ÅÆ4Ç5È5É5Ê6Ë6Ì6Í6Î8Ï8Ð8Ñ8Ò8Ó8Ô8Ô898:<Õ=Ö>×JZJØJÙJÚJÛJÜJÝJÞJßJPJNJOJQRàWáYâYãYäYåYXYæmçmçmçèqK[é[ê[ë[ì^ílîlïnðnñpòpó`ª`€`ô`õ`ö`÷`ø`ù`ú`ûf¿fÀfüfýfþfÿf¾k€k�k‚kƒk„u…u†u‡uˆw‰w!yŠy‹xŒ|�|�|�Ž|��|��|�‘|’|“|”|•�–�—s˜s™s_ƒ§ˆšˆ›ˆœˆ�‰ž‰Ÿ‰ ‰¡¢£¤¥¦§ã¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉ¿ÀÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâ¦ãtbtätg………å…æ†ç†è†é†ê†ë†ì†í†î†ï†ðŠñŠòŠóŠôŠõ‹ö‹÷‹ø‹ù‹Œ�ú�û�ü�ý�þ�ÿ�€���Ž�‚�ƒ‘�~�–�„�…�†�‡}ò“ˆ”‹•‰•Š—‹—Œ˜�™Žšþšc��ž�Ÿ‘Ÿ’Ÿ“Ÿ”Ÿ•Ÿ–Ÿ— ˜ ™ š7›œ¢£�¤¥žŸ ¡¨Ý¨¢¨£¨¤¨¥°¦°§±¨²©³ª³«³¬³­³®³¯³°³±³²³«³³³´³µ³¶³·³©³¬³¸³¹³º³Ê³»³¼³½³¾³¿³À³Á³Â³Ã³Ä³Å³Æ³Ç³È³É³Ê³Ë³Ì³ÍºvºÎºÏºÐºÿºÙºÑºÒºÓ½Ô½Õ½Ö½×½Ã½Ø½Ù½Ú½Û½ÜÁÝÁÞÁßÁàÁáÁâÁãÁäÄåÅæÅçÅèÅéÅêÅ‘ÅëÅÌÈìÈíÈ´ÈÇÈîÈïÈðÈñÈòÈóÈôÈõËö÷øÌùÌúÎûÏÉÏüÏýÏþÏÿЀÐ�ЂЃЄЅІЇЈЉЊЋЌÐ�ÐŽÐ�Ð�БВГДЕЖЗИڙۚۛۼܡܜÜ�ÞéäßæžçŸç ç¡ç¢çðç£ë¤ëêë¤îìîìîì¥îìŽîì�îì¦îì§îáï¨ñMñMñM¥ñM©ñMªñM«ñàó¬ó­ôíôíôí¥ôí®ôí¯ôí¦ôâõ°õ±õ²õ³õ´öÆöÂöµö¶ö·ö¸ö¹öºø»ú¼ú½ú¾ú¿úÀúÁúÂúÃúÄúÅúÆúÇûÈûÉûÊüËýÌýÍýÎýÏýÐýÑýÒýÓýÔýÕýÖýרÙÚÛÜÝ¡œ˜ÞªšÆÂ‘’“‚ƒßàá∉ãä‹åæçèéêëìíîïðñòó� �ô–õ–ö–÷–ø–ù–ú–û–ü–ý–þ—ÿ˜€˜�˜‚˜ƒ˜„˜…˜†˜‡˜ˆ˜‰šŠš‹šŒš�š�šŽš�›�œ‘œ’œ“œ”œ£�ž¢ ¢•¢–¢—¢˜¢™¢šŸ›ŸœŸ�ŸžŸŸŸ Ÿ¡Ÿ¢Ÿ£Ÿ¤Ÿ¥¤¦ § § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì ÍÎÏÐ Ñ Ò ÑÓÔÕÖרÙÚÛÜÜÜÝÞßàáâãäåÎæç¨èéêëìííîÙ× ïïgðñ¬òóÎôõö÷øùú"û#ü$ý$²$þ$ÿ$€%�%‚(ƒ(„+…+†+ª,‡-ˆ-‰-Š-ê-‘-ë-Ì-‹-Œ-�.û/ý/²/þ/ÿ/€0Ž0�0�0‘0’0“0”0•0–0—0˜0™0š0›0œ0�0ž0Ÿ0 0¡0¢0£0¤¥¦§¥¨©;ª;«;«;«¬;«­;«®<¾<¯<°<±<²=³>´>µ>¶>·>¸>?>@>A>B>C>¹>º>»>¼>½>¾>¿>À>Á>ÂDÃDÄDÄDÄÅDÆDÆDÇDÈDÉDÉDÉÊEðËÌÍEÎEÏEÐEÃEÑEÒEÒFÓFÃFÔFÕFÖG×GØGÙGÚGÛGÜGÝGÞGßHàHáHâHãHäHåHæHçHèHéHêIëIëIëìJíJîJïJðJñJòJóSôSõSöSöT÷TøTùTÏTÃTúTûTüTýTþTþTþÿT€U�V‚WƒWáY„[…[†[‡[ˆ[‰[Š[‹[Œ[�[Ž[�^�^‘f’Îh“Îæ”Îô•Îæ–f—f˜f™fšk›lœl�lžlŸl Î¡¢Î£¤Îæ¥qKr¦s§s‡w¨w!x©xªx«x¬x­x®x¯x°x±x²x³x´xµy¶y·y¸z¹{º|»Îæ¼½¾¿ÀÁÂÀĀŀƀ¯€°€Ç€È€É€Ê€Ë€Ì€Í€ÎÏÐт҄ӄԈՈֈ׉؉ىÚËÛÜËÛÝËÌÞËÌßËÛàËÛáËÛâËÛã‘ä뾌Ծ‘ç‘è‘’é’ê’•’ë’ì’í’î˜ïŸðÎæñòóôõö÷¨ø¨ù¨¢¯ú¯œ¯ü¯Ù¯ðËÌû³ü³ý³þ³ÿ³€ ³� ³‚ ·ƒ ·„ ·… ·† ·‡ ·ˆ ·‰ ·Š ·Š ¸‹ ¸‹ ¸‹ Œ ¸‹ � ¸‹ Ž ¸‹ � ¹� ¹� ¹� ‘ ¹� ’ Îô“ Îæ” Îæ• º– º— º˜ º™ ºvºvš ºv› ½ÔÁÝÎæœ Åæ� ž Ÿ � ž   � ž ¡ ЀЀ¢ Ѐ£ ܤ Îæ¥ Þ¦ Þ§ Þ¨ ä© äª ä« ä¬ äÒä¬ ä­ å® å¯ Îæ° α ² ë³ ë´ îµ ï¶ ñ· ñ¸ ô¹ ùº ùº ùº » ùº ¼ ùº ’ ν ¾ ν ¿ ν À ú¼ú¼Ëú¼Úú¼› Á � �à �Ä �Å �Æ �Ç ŽÈ ŽÉ ŽÊ ŽË ŽÌ ���‘�’�“�Þ�Í �×�Î �Ý�Ú�ß�Û�Ï �Ð �ñ”Ñ ”Ò ”Ó ”Ô ”Õ ”Ö ”× ”Ø ”Ù ”Ú ”Û ”Ü ”Ý ”Þ ”ß ”à ”á •â •ã •ä •å •æ •ç •è •é •ê •ë •ì –í –î –ï –ú–ð ˜ñ ˜…˜ò ˜ó ˜ô œ’¢õ ¢ö ¢÷ ¢ø ¢ù ¢ú ¢û ¢ü ¢ý ¢þ ÿ € rel8-1.7.0.0-inplaceRel8 Rel8.Decoder Rel8.Encoder Rel8.ArrayRel8.Expr.TimeRel8.Expr.Text Rel8.Expr.Num Rel8.TabulateRel8.Table.Verifyrel8Rel8.Aggregate.FoldData.Semigroup.FoldablefoldMap1QueryRel8.FCFRel8.Generic.MapRel8.Generic.RecordRel8.Kind.Algebra Rel8.OrderascdescData.Functor.Contravariant>$<Rel8.Query.OpaleyeRel8.Schema.DictRel8.Schema.EscapeRel8.Schema.KindRel8.Schema.HTable.ProductRel8.Schema.NullRel8.Schema.QualifiedNameRel8.Schema.TableRel8ableNameRel8.Type.Builder.ByteStringRel8.Type.Builder.FoldRel8.Type.Builder.TimeRel8.Type.DecimalRel8.Type.DecoderRel8.Type.EncoderRel8.Type.NameRel8.Type.InformationDBTypeRel8.Type.NullableRel8.Type.ParserRel8.Type.ArrayRel8.Type.Parser.ByteStringRel8.Type.Parser.Time Rel8.TypeRel8.Type.JSONEncodedRel8.Type.JSONBEncoded JSONEncoded Rel8.Type.Eq Rel8.Type.Ord Rel8.Type.Num fromIntegralRel8.Type.Enum $dmenumValue $dmenumerateRel8.Schema.SpecRel8.Schema.Result Rel8.ColumnRel8.Schema.HTable $dmhdicts $dmhfield $dmhspecs $dmhtabulate $dmhtraverseRel8.Schema.HTable.MapTableRel8.Schema.HTable.NullifyRel8.Schema.HTable.LabelRel8.Generic.Table.Record Rel8.Generic.Construction.RecordRel8.Schema.HTable.Identity Rel8.TableExpr AggregateInsert$dmfromColumns $dmfromResult $dmtoColumns $dmtoResultRel8.Table.TransposeRel8.Table.ColsRel8.Schema.HTable.VectorizeRel8.Schema.HTable.NonEmptyRel8.Schema.HTable.ListRel8.Schema.Field ProjectionRel8.Table.ProjectionTableRel8.Expr.OpaleyeOpaleyePrimExprRel8.Expr.SerializelitRel8.Expr.Bool Data.Boolboolwhere_32Rel8.Expr.Nullnullable Data.Maybe isNothingisJustRel8.Expr.FunctionRel8.Expr.ArrayRel8.Type.ReadShowRel8.Type.Semigroup6Rel8.Type.Monoid Rel8.ExprRel8.Table.UndefinedRel8.Table.SerializeRel8.Table.BoolRel8.Table.Alternative MaybeTableRel8.Schema.NameRel8.Table.OpaleyeRel8.Table.NameRel8.Statement.WhereRel8.Statement.SetRel8.Statement.OnConflictRel8.Query.ValuesunionRel8.Kind.ContextRel8.Schema.Context.NullifyRel8.Expr.SubscriptRel8.Expr.ShowRel8.Expr.SequenceRel8.Expr.ReadRel8.Expr.Order Rel8.Expr.Ord4Rel8.Expr.NonEmptyRel8.Expr.List Rel8.Expr.Eq Rel8.Table.Eq $dmeqTableRel8.Table.Ord $dmordTableRel8.Table.OrderRel8.Query.Set Rel8.QueryRel8.Statement.RowsRel8.Query.OrderRel8.Query.MaterializeRel8.Query.LoopunionAllRel8.Query.LimitRel8.Query.RebindRel8.Query.FunctionRel8.Query.Filter Control.MonadguardRel8.Query.EvaluateRel8.Query.EachRel8.Query.ExistsRel8.Query.DistinctPreludedivmodquotremRel8.Expr.DefaultnextvalRel8.AggregatesumfalseorsumOnData.ProfunctorlmapRel8.Table.NullifyRel8.Aggregate.FunctionRel8.Type.String Rel8.Type.SumRel8.Expr.Aggregate filterWhereData.Scientific Scientific Rel8.Type.TagRel8.Schema.HTable.TheseRel8.Schema.HTable.MaybeRel8.Table.Maybe fromMaybetraverseMaybeTableRel8.Table.NullnullnullifyunsafeUnnullifyRel8.Table.NonEmptysome nullTableRel8.Column.NonEmptyRel8.Table.ListmanylistAggRel8.Table.AggregatefilterWhereOptional stringAggRel8.Column.ListRel8.Query.Null catMaybesRel8.Column.NullRel8.Table.Aggregate.MaybeRel8.Table.TheseData.These.CombinatorsisThisisThatisThesehasHerehasTherejustHere justThere justTableRel8.Column.TheseRel8.Query.MaybeRel8.Query.Aggregate Aggregator1Rel8.StatementselectinsertupdatedeletenowRel8.Statement.SelectRel8.Statement.UsingRel8.Query.SQLRel8.Statement.RunHasql Statement NoReturningRel8.Statement.ReturningUpdateDeleteRel8.Statement.UpdateRel8.Statement.PreparedrunRel8.Statement.InsertvaluesRel8.Statement.ViewRel8.Statement.DeleteRel8.Statement.SQLRel8.Query.ListControl.ApplicativeRel8.Column.MaybeRel8.Schema.HTable.EitherRel8.Table.EitherRel8.Query.EitherRel8.Column.EitherRel8.Query.Thesefilter nothingTabletrueData.Semialignalign alignWithrpadZip rpadZipWithlpadZip lpadZipWithzipzipWithQ materialize1Rel8.Generic.Table.ADTRel8.Generic.TableRel8.Generic.Rel8able$dmgfromColumns$dmgfromResult $dmgtoColumns $dmgtoResultRel8.Generic.Construction.ADTRel8.Generic.ConstructionRel8.Table.HKDRel8.Column.LiftRel8.Table.ADTRel8.Table.Rel8ableRel8.Type.CompositeRel8.Column.ADT Rel8.WindowRel8.Query.WindowwindowRel8.Table.Window cumulative aggregateRel8.Expr.WindoworderPartitionByRel8.Query.IndexedFoldSemiFullOrderSqlNullable HomonullableNotNull QualifiedNameschemaname TableSchemacolumnsDecodertextbinaryParser parseDecoderEncoderquoteTypeName arrayDepth modifiersTypeInformationtypeName delimiterdecodeencodemapTypeInformationparseTypeInformationtypeInformationfromJSONEncoded JSONBEncodedfromJSONBEncodedDBEqDBMinDBMaxDBOrd DBFloating DBFractional DBIntegralDBNumEnumableDBEnum enumValue enumTypeName enumerateEnumResultColumnHTableColumnsContext FromExprs Transpose toColumns fromColumns fromResulttoResult TransposesField Biprojectable biproject Projectableproject ProjectingReadShow fromReadShowunsafeCastExprunsafeCoerceExprunsafePrimExpr unsafeLiterallitExprlistOf nonEmptyOf DBSemigroup<>.DBMonoid memptyExpr&&.||.not_and_or_boolExprcaseExprcoalesceisNull isNonNullmapNull liftOpNull Argumentsfunction rawFunctionbinaryOperatorrawBinaryOperatorAlternativeTable emptyTableAltTable<|>:SelectsnamesFromLabelsnamesFromLabelsWith castTableUpsert updateWhereset predicateindex OnConflictAbort DoNothingDoUpdateunsafeSubscriptunsafeSubscripts SerializableToExprs head1Expr index1Expr last1Expr length1ExprheadExpr indexExprlastExpr lengthExprtodaytoDayfromDayaddDaysdiffDays subtractDaysaddTimediffTime subtractTime scaleIntervalsecondsecondsminuteminuteshourhoursdaydaysweekweeksmonthmonthsyearyears++.~.~*!~!~* bitLength charLengthlower octetLengthupperasciibtrimchrconvert convertFrom convertToinitcapleftlengthlengthEncodinglpadltrimmd5pgClientEncoding quoteIdent quoteLiteral quoteNullable regexpReplaceregexpSplitToArrayrepeatreplacereverserightrpadrtrim splitPartstrpossubstr translatelikeilike unsafeDefaultcase_ nullsFirst nullsLast<.<=.>.>=.?>=? leastExpr greatestExpr==./=.==?/=?in_EqTableeqTable==:/=:OrdTableordTable<:<=:>:>=:leastgreatestascTable descTable intersect intersectAllexcept exceptAllorderByloop loopDistinctlimitoffsetrebind queryFunctionevaluateeachexistspresentabsentwithwithBywithout withoutBydistinct distinctOn distinctOnBy realToFracceilingdivModquotRemfloorroundtruncate Aggregator Aggregator' toAggregator1 toAggregatoraggregateFunctionrawAggregateFunctionDBStringDBSumcountcountOn countDistinctcountDistinctOn countStar countWhere countWhereOnandandOnorOnmaxmaxOnminminOnsumWhereavgavgOnmodemodeOn percentile percentileOnpercentileContinuouspercentileContinuousOnhypotheticalRankhypotheticalDenseRankhypotheticalPercentRankhypotheticalCumeDist listAggExpr listAggExprOnnonEmptyAggExprnonEmptyAggExprOn listCatExpr listCatExprOnnonEmptyCatExprnonEmptyCatExprOndistinctAggregateisNothingTable isJustTable maybeTablefromMaybeTable$?nameMaybeTable NullTable isNullTableisNonNullTable nullableTable nullifyTableunsafeUnnullifyTable nameNullTable toMaybeTable toNullTable NonEmptyTable$+ nonEmptyTablenameNonEmptyTablehead1index1last1length1 HNonEmpty ListTable$* listTable nameListTableheadlastgroupBy groupByOn listAggOn nonEmptyAgg nonEmptyAggOnlistCat listCatOn nonEmptyCat nonEmptyCatOnorderAggregateByHListelemelem1catNull catNullTableHNulloptionalAggregateaggregateJustTableaggregateJustTable1aggregateMaybeTable TheseTable isThisTable isThatTable isThoseTable hasHereTable hasThereTable justHereTablejustThereTablealignMaybeTable thisTable thatTable thoseTable theseTableaggregateThisTableaggregateThisTable1aggregateThatTableaggregateThatTable1aggregateThoseTableaggregateThoseTable1aggregateHereTableaggregateHereTable1aggregateThereTableaggregateThereTable1aggregateTheseTablenameTheseTableHTheseoptional catMaybeTable aggregate1 countRows showQueryrun_runNrun1runMaybe runVector Returning returningfromtargetprepared onConflictrowsinto createViewcreateOrReplaceView deleteWhereusing showDelete showInsert showUpdate showStatementshowPreparedStatementmanyExprsomeExpr catListTablecatNonEmptyTablecatList catNonEmptyHMaybe EitherTable isLeftTable isRightTable eitherTable leftTable rightTableaggregateLeftTableaggregateLeftTable1aggregateRightTableaggregateRightTable1aggregateEitherTablenameEitherTable keepLeftTablekeepRightTablebitraverseEitherTableHEitheralignBy keepHereTable loseHereTablekeepThereTableloseThereTable keepThisTable loseThisTable keepThatTable loseThatTablekeepThoseTableloseThoseTablebitraverseTheseTable Tabulation fromQuerytoQuery liftQuerythroughlookuporder leftAlign leftAlignWith rightAlignrightAlignWith similarity difference$fMonoidPredicate$fSemigroupPredicate$fContravariantPredicate$fMonoidTabulation$fSemigroupTabulation$fAlternativeTableTabulation$fAltTableTabulation$fMonadTabulation$fBindTabulation$fApplicativeTabulation$fApplyTabulation$fProjectableTabulation$fFunctorTabulation$fBifunctorTabulation$fBiprojectableTabulation KRel8ableNameHKDDeconstructHKD ConstructHKDBuildHKDHKDableHKDbuildHKD constructHKDdeconstructHKDnameHKDLiftNameADTDeconstructADT ConstructADTBuildADTADTableADTbuildADT constructADTdeconstructADTnameADT DBCompositecompositeFieldscompositeTypeName Compositecompose decomposeHADT PartitionWindowover partitionBy rowNumberrank denseRank percentRankcumeDistntile currentRowlaglagOnleadleadOn firstValue firstValueOn lastValue lastValueOnnthValue nthValueOnindexedSomeTableSchemashowCreateTablecheckedShowCreateTablegetSchemaErrors$fDBTypeRelkind$fShowTypeInfo$fShowTableInfo$fShowColumnInfo$fShowColumnError$fShowCheckEnv $fGenericCast$fRel8ableCast$fGenericPGTable$fRel8ablePGTable$fGenericAttribute$fRel8ableAttribute$fGenericPGCast$fRel8ablePGCast$fGenericPGNamespace$fRel8ablePGNamespace$fGenericPGType$fRel8ablePGType$fGenericPGAttribute$fRel8ablePGAttribute$fGenericPGClass$fRel8ablePGClass $fDBTypeOid $fDBEqOid $fShowOid $fShowRelkind $fDBEqRelkind $fShowCast$fShowAttribute $fShowPGTable $fShowPGCast$fShowPGNamespace $fShowPGType$fShowPGAttribute $fShowPGClassbase Data.FoldablefoldMapFallbackEmptyEvalExpIdMapGMapGRecord GRecordablegrecord gunrecordRecordunrecordAlgebraProductSum KnownAlgebra algebraSingSAlgebraSProductSSumGHC.Base<> fromOpaleye mapOpaleye toOpaleyeunsafePeekQueryzipOpaleyeWithDictescapeHProductNullifyNullityNull Unnullify GHC.MaybeNothing$fIsStringQualifiedNameppQualifiedNameshowQualifiedNameshowQualifiedOperatorppTable bytestring interfoldMapcalendarDiffTime localTime timeOfDayutcTime resolution PowerOf10$fIsStringTypeName showTypeName NullableOrNot NonNullableparsearray arrayTypeNameextractArrayElementlistTypeInformationnonEmptyTypeInformationquoteArrayElement$fDBTypeIPRange $fDBTypeValue $fDBTypeUUID$fDBTypeByteString$fDBTypeByteString0 $fDBTypeCI $fDBTypeCI0 $fDBTypeText $fDBTypeText0$fDBTypeCalendarDiffTime$fDBTypeTimeOfDay$fDBTypeLocalTime $fDBTypeDay$fDBTypeUTCTime $fDBTypeFixed$fDBTypeScientific$fDBTypeDouble $fDBTypeFloat $fDBTypeInt64 $fDBTypeInt32 $fDBTypeInt16 $fDBTypeChar $fDBTypeBoolÎaeson-2.2.3.0-2aaacadf5014bf2546bebd07da3224a7fd2f86b0698e1386324a7e426d4094feData.Aeson.Types.ToJSONToJSONData.Aeson.Types.FromJSONFromJSON specificationSpecinfolabelsnullity nullifier unnullifier unvectorizer vectorizerTColumn HProductField htabulatehfieldhdictshspecshfoldMaphmap htabulateA htabulateP htraversePhtraversePWithField htraverse_HConstrainTableHField htraversehproject HMapTable unHMapTableHMapTableFieldMapSpecmapInfo Precompose precomposedghc-prim GHC.TypesTypehguardhnullifyhnulls hunnullifyHNullifyhlabelhrelabelhunlabelHLabelGColumnsGContext GSerialize gfromResult gtoResultGTable gfromColumnsgtable gtoColumns FromColumns GConstructGConstructable gconstruct gdeconstruct GConstructorGFields Representablegindex gtabulate ToColumns HIdentity unHIdentity CongruentTColumnsTContext TFromExprs TSerializeTTable TTransposefromColstoColsColshappendhcolumnhemptyhtraverseVectorP hunvectorize hvectorize hvectorizeAFirstgetFirst HVectorizeHNonEmptyTable HListTablefieldsapplycastExpr fromColumn fromPrimExpr mapPrimExpr scastExprsunsafeCastExprtoColumn toPrimExprtraverseFieldPtraversePrimExprzipPrimExprsWithslitExpr sparseValue nullableExprmaybefmapMaybeliftA2 nullableOfsnullunsafeLiftOpNull unsafeMapNull primFunctionsappendsappend1semptyslistOf snonEmptyOfGHC.ReadReadGHC.ShowShowMonoid undefined litHTableppColumn attributes binaryspec distinctspecexprsexprsWithNames fromOrderifPP relExprPPtable tableFields unpackspec valuesspecviewnamesFromLabelsWithA showLabels showNamesppWhereppSet ppOnConflictreturn Reifiable contextSingSContextSExprSFieldSNameSResultabsurdguardernullifiableOrNotNonNullifiabilityNFieldNResultNullifiabilityNExprNName Nullifiablenullifiabilitytime-1.12.2-7014Data.Time.Calendar.DaysDayshowreadsread shead1Expr sindex1Expr slast1Expr sheadExpr sindexExpr slastExpr GHC.Classes==/=TrueBool<<=>>= $fMonoidQuerymempty$fSemigroupQuery$fAlternativeTableQuery$fAltTableQueryRowsList RowsAffectedSingleVectorVoidhrebindinQuery ApplicativeÒprofunctors-5.6.3-efc9a4499d0843f2684e698f21fc88a21a374aee026273be61a897b1a4e0c31eData.Profunctor.Unsafe ProfunctorÝproduct-profunctors-0.11.1.1-e4aea7d95d4b5c806a39d421fa516f5d64777fee4a0283d1604f3b798112e93eData.Profunctor.Product.ClassProductProfunctorfilterWhereExplicitunsafeMakeAggregatoraggregateNullifyDouble stringAggOn groupByExpr groupByExprOn slistAggExpr slistCatExprsnonEmptyAggExprsnonEmptyCatExprisLeftisRight EitherTagIsLeftIsRightMaybeTagIsJustTag HTheseTablehherehhereTaghthere hthereTag HMaybeTablehjusthtagJustpure$$fMonadMaybeTable$fApplicativeMaybeTablemakeMaybeTableunsafeFromJustTablejusttagNonEmptyÌthese-1.2.1-0e273ac3a11271a02fecebf97f043eb0106dd4dde4d7d4abe106c3beff7d8d10 Data.TheseTheseThisThatherethere aggregateUMonadppDecodeStatementstatementNoReturningstatementReturning ppPrimSelectppRowsppSelect OptimizedUnitppFromppUsingStringGHC.IntInt64 ppReturning runReturningppUpdateinputppInsertppIntoppDelete HEitherTablehlefthright Data.EitherEitherLeftRightpeek GColumnsADT GColumnsADT' GSerializeADTgfromResultADT gtoResultADTGSerializeADT' ggfromResult ggtoResultGAlgebra GGColumns GGSerializeGRep GFromExprs deserialize serialize GBuildADT GConstructADTGConstructableADT gbuildADT gconstructADTgdeconstructADT gunbuildADTGConstructorADT GConstructors GMakeableADTgmakeADTRepresentableConstructorsgcindex gctabulateRepresentableFieldsgfindex gftabulateggbuild ggconstruct ggdeconstructggdeconstructAggnameGGBuild GGBuildable GGConstructGGConstructable GGDeconstructGGNamedeconstructAHKD BuildableHKDConstructableHKDHKDRepdeconstructAADTADTRep BuildableADTConstructableADTlagExpr lagExprOnleadExpr leadExprOnfirstValueExprfirstValueExprOn lastValueExprlastValueExprOn nthValueExprnthValueExprOn pShowTable