diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,21 @@
+## 0.3.1
+
+* SQL code generator escapes column names, so table column names can
+  be the same as SQL keywords.
+* Add `like` operator
+* Add the types `PGCitext`, `PGArray`, `PGBytea`
+* 
+	
+## 0.3
+
+* Replace `Default QueryRunner` with a new class `DefaultQueryRunnerColumn`, migrate with `s/Default QueryRunner/DefaultQueryRunnerColumn` and `s/def/queryRunnerColumnDefault/`
+* Remove `ShowConstant`, use the monomorphic functions defined in the new module `Opaleye.PGTypes` instead. You will need to replace `Column Bool` with `Column PGBool` et.c. in query signatures
+* Re-export more modules from `Opaleye`
+* Add `boolAnd`, `boolOr,` `max`, and `min` aggregators
+* Add `lower` and `upper`
+* Add operator fixities
+* Add `maybeToNullable`
+* Add column instances for `Bool`, `UUID`, `Text`, and `UTCTime`
+* Expose fieldQueryRunnerColumn from Opaleye.RunQuery
+* Add `unsafeCast`
+* Re-export `Unpackspec` from `Opaleye.Manipulation`
diff --git a/Doc/Tutorial/DefaultExplanation.lhs b/Doc/Tutorial/DefaultExplanation.lhs
new file mode 100644
--- /dev/null
+++ b/Doc/Tutorial/DefaultExplanation.lhs
@@ -0,0 +1,228 @@
+> {-# LANGUAGE FlexibleContexts #-}
+> module DefaultExplanation where
+>
+> import Opaleye (Column, Nullable, QueryRunner, Query,
+>                 PGInt4, PGBool, PGText, PGFloat4)
+> import qualified Opaleye as O
+> import qualified Opaleye.Internal.Binary as Internal.Binary
+> import Opaleye.Internal.Binary (Binaryspec)
+>
+> import Data.Profunctor.Product ((***!), p4)
+> import Data.Profunctor.Product.Default (Default, def)
+> import qualified Database.PostgreSQL.Simple as SQL
+
+Introduction
+============
+
+Instances of `ProductProfunctor` are very common in Opaleye.  They are
+first-class representations of various transformations that need to
+occur in certain places.  The `Default` typeclass from
+product-profunctors is used throughout Opaleye to avoid API users
+having to write a lot of automatically derivable code, and it deserves
+a thorough explanation.
+
+Example
+=======
+
+By way of example we will consider the Binaryspec product-profunctor
+and how it is used with the `unionAll` operation.  The version of
+`unionAll` that does not have a Default constraint is called
+`unionAllExplicit` and has the following type.
+
+> unionAllExplicit :: Binaryspec a b -> Query a -> Query a -> Query b
+> unionAllExplicit = O.unionAllExplicit
+
+What is the `Binaryspec` used for here?  Let's take a simple case
+where we want to union two queries of type `Query (Column PGInt4,
+Column PGText)`
+
+> myQuery1 :: Query (Column PGInt4, Column PGText)
+> myQuery1 = undefined -- We won't actually need specific implementations here
+>
+> myQuery2 :: Query (Column PGInt4, Column PGText)
+> myQuery2 = undefined
+
+That means we will be using unionAll at the type
+
+> unionAllExplicit' :: Binaryspec (Column PGInt4, Column PGText) (Column PGInt4, Column PGText)
+>                   -> Query (Column PGInt4, Column PGText)
+>                   -> Query (Column PGInt4, Column PGText)
+>                   -> Query (Column PGInt4, Column PGText)
+> unionAllExplicit' = unionAllExplicit
+
+Since every `Column` is actually just a string containing an SQL
+expression, `(Column PGInt4, Column PGText)` is a pair of expressions.
+When we generate the SQL we need to take the two pairs of expressions,
+generate new unique names that refer to them and produce these new
+unique names in another value of type `(Column PGInt4, Column
+PGText)`.  This is exactly what a value of type
+
+    Binaryspec (Column PGInt4, Column PGText) (Column PGInt4, Column PGText)
+
+allows us to do.
+
+So the next question is, how do we get our hands on a value of that
+type?  Well, we have `binaryspecColumn` which is a value that allows
+us to access the column name within a single column.
+
+> binaryspecColumn :: Binaryspec (Column a) (Column a)
+> binaryspecColumn = Internal.Binary.binaryspecColumn
+
+`Binaryspec` is a `ProductProfunctor` so we can combine two of them to
+work on a pair.
+
+> binaryspecColumn2 :: Binaryspec (Column a, Column b) (Column a, Column b)
+> binaryspecColumn2 = binaryspecColumn ***! binaryspecColumn
+
+Then we can use `binaryspecColumn2` in `unionAllExplicit`.
+
+> theUnionAll :: Query (Column PGInt4, Column PGText)
+> theUnionAll = unionAllExplicit binaryspecColumn2 myQuery1 myQuery2
+
+Now suppose that we wanted to take a union of two queries with columns
+in a tuple of size four.  We can make a suitable `Binaryspec` like
+this:
+
+> binaryspecColumn4 :: Binaryspec (Column a, Column b, Column c, Column d)
+>                                   (Column a, Column b, Column c, Column d)
+> binaryspecColumn4 = p4 (binaryspecColumn, binaryspecColumn,
+>                         binaryspecColumn, binaryspecColumn)
+
+Then we can pass this `Binaryspec` to `unionAllExplicit`.
+
+The problem and 'Default' is the solution
+=========================================
+
+Constructing these `Binaryspec`s explicitly will become very tedious
+very fast.  Furthermore it is completely pointless to construct them
+explicitly because the correct `Binaryspec` can automatically be
+deduced.  This is where the `Default` typeclass comes in.
+
+`Opaleye.Internal.Binary` contains the `Default` instance
+
+    instance Default Binaryspec (Column a) (Column a) where
+      def = binaryspecColumn
+
+That means that we know the "default" way of getting a
+
+    Binaryspec (Column a) (Column a)
+
+However, if we have a default way of getting one of these, we also
+have a default way of getting a
+
+    Binaryspec (Column a, Column b) (Column a, Column b)
+
+just by using the `ProductProfunctor` product operation `(***!)`.  And
+in the general case for a product type `T` with n type parameters we
+can automatically deduce the correct value of type
+
+    Binaryspec (T a1 ... an) (T a1 ... an)
+
+(This requires the `Default` instance for `T` as generated by
+`Data.Profunctor.Product.TH.makeAdaptorAndInstance`, or an equivalent
+instance defined by hand).  It means we don't have to explicitly
+specify the `Binaryspec` value.
+
+Instead of writing `theUnionAll` as above, providing the `Binaryspec`
+explicitly, we can instead use a version of `unionAll` which
+automatically uses the default `Binaryspec` so we don't have to
+provide it.  This is exactly what `Opaleye.Binary.unionAll` does.
+
+> unionAll :: Default Binaryspec a b
+>           => Query a -> Query a -> Query b
+> unionAll = O.unionAllExplicit def
+>
+> theUnionAll' :: Query (Column PGInt4, Column PGText)
+> theUnionAll' = unionAll myQuery1 myQuery2
+
+In the long run this prevents writing a huge amount of boilerplate code.
+
+A further example: `QueryRunner`
+==============================
+
+A `QueryRunner a b` is the product-profunctor which represents how to
+turn run a `Query a` (currently on Postgres) and return you a list of
+rows, each row of type `b`.  The function which is responsible for
+this is `runQuery`
+
+> runQueryExplicit :: QueryRunner a b -> SQL.Connection -> Query a -> IO [b]
+> runQueryExplicit = O.runQueryExplicit
+
+Basic values of `QueryRunner` will have the following types
+
+> intRunner :: QueryRunner (Column PGInt4) Int
+> intRunner = undefined -- The implementation is not important here
+>
+> doubleRunner :: QueryRunner (Column PGFloat4) Double
+> doubleRunner = undefined
+>
+> stringRunner :: QueryRunner (Column PGText) String
+> stringRunner = undefined
+>
+> boolRunner :: QueryRunner (Column PGBool) Bool
+> boolRunner = undefined
+
+Furthermore we will have basic ways of running queries which return
+`Nullable` values, for example
+
+> nullableIntRunner :: QueryRunner (Column (Nullable PGInt4)) (Maybe Int)
+> nullableIntRunner = undefined
+
+If I have a very simple query with a single column of `PGInt4` then I can
+run it using the `intRunner`.
+
+> myQuery3 :: Query (Column PGInt4)
+> myQuery3 = undefined -- The implementation is not important
+>
+> runTheQuery :: SQL.Connection -> IO [Int]
+> runTheQuery c = runQueryExplicit intRunner c myQuery3
+
+If my query has several columns of different types I need to build up
+a larger `QueryRunner`.
+
+> myQuery4 :: Query (Column PGInt4, Column PGText, Column PGBool, Column (Nullable PGInt4))
+> myQuery4 = undefined
+>
+> largerQueryRunner :: QueryRunner
+>       (Column PGInt4, Column PGText, Column PGBool, Column (Nullable PGInt4))
+>       (Int, String, Bool, Maybe Int)
+> largerQueryRunner = p4 (intRunner, stringRunner, boolRunner, nullableIntRunner)
+>
+> runTheBiggerQuery :: SQL.Connection -> IO [(Int, String, Bool, Maybe Int)]
+> runTheBiggerQuery c = runQueryExplicit largerQueryRunner c myQuery4
+
+But having to build up `largerQueryRunner` was a pain and completely
+redundant!  Like the `Binaryspec` it can be automatically deduced.
+`Karamaan.Opaleye.RunQuery` already gives us `Default` instances for
+the following types (plus many others, of course!).
+
+* `QueryRunner (Column PGInt4) Int`
+* `QueryRunner (Column PGText) String`
+* `QueryRunner (Column Bool) Bool`
+* `QueryRunner (Column (Nullable Int)) (Maybe Int)`
+
+Then the `Default` typeclass machinery automatically deduces the
+correct value of the type we want.
+
+> largerQueryRunner' :: QueryRunner
+>       (Column PGInt4, Column PGText, Column PGBool, Column (Nullable PGInt4))
+>       (Int, String, Bool, Maybe Int)
+> largerQueryRunner' = def
+
+And we can produce a version of `runQuery` which allows us to write
+our query without explicitly passing the product-profunctor value.
+
+> runQuery :: Default QueryRunner a b => SQL.Connection -> Query a -> IO [b]
+> runQuery = O.runQueryExplicit def
+>
+> runTheBiggerQuery' :: SQL.Connection -> IO [(Int, String, Bool, Maybe Int)]
+> runTheBiggerQuery' c = runQuery c myQuery4
+
+Conclusion
+==========
+
+Much of the functionality of Opaleye depends on product-profunctors
+and many of the values of the product-profunctors are automatically
+derivable from some base collection.  The `Default` typeclass and its
+associated instance derivations are the mechanism through which this
+happens.
diff --git a/Doc/Tutorial/Main.hs b/Doc/Tutorial/Main.hs
--- a/Doc/Tutorial/Main.hs
+++ b/Doc/Tutorial/Main.hs
@@ -1,6 +1,7 @@
 import TutorialBasic ()
 import TutorialManipulation ()
 import TutorialAdvanced ()
+import DefaultExplanation ()
 
 main :: IO ()
 main = return ()
diff --git a/Doc/Tutorial/TutorialBasic.lhs b/Doc/Tutorial/TutorialBasic.lhs
--- a/Doc/Tutorial/TutorialBasic.lhs
+++ b/Doc/Tutorial/TutorialBasic.lhs
@@ -67,11 +67,12 @@
 To query a table we use `queryTable`.
 
 (Here and in a few other places in Opaleye there is some typeclass
-magic going on behind the scenes.  However, you never *have* to use
-typeclasses.  All the magic that typeclasses do is also available by
-explicitly passing in the "typeclass dictionary".  For this example
-file we will always use the typeclass versions because they are
-simpler to read and the typeclass magic is essentially invisible.)
+magic going on behind the scenes to reduce boilerplate.  However, you
+never *have* to use typeclasses.  All the magic that typeclasses do is
+also available by explicitly passing in the "typeclass dictionary".
+For this example file we will always use the typeclass versions
+because they are simpler to read and the typeclass magic is
+essentially invisible.)
 
 > personQuery :: Query (Column PGText, Column PGInt4, Column PGText)
 > personQuery = queryTable personTable
@@ -345,7 +346,6 @@
 SELECT name0,
        age0,
        address0,
-       name1,
        birthday1
 FROM (SELECT name as name0,
              age as age0,
@@ -702,7 +702,17 @@
 ON name0 = name1
 
 
+A comment about type signatures
+-------------------------------
 
+We mentioned that Opaleye uses typeclass magic behind the scenes to
+avoid boilerplate.  One consequence of this is that the compiler
+cannot infer types in some cases. Use of `leftJoin` is one of those
+cases.  You will generally need to provide a type signature yourself.
+If you see the compiler complain that it cannot determine a `Default`
+instance then specify more types.
+
+
 Newtypes
 ========
 
@@ -780,9 +790,9 @@
 > --          -> Query columns -> IO [haskells]
 
 It converts a "record" of Opaleye columns to a list of "records" of
-Haskell values.  Because this particular formulation uses typeclasses
-please put type signatures on everything in sight to minimize the
-number of confusing error messages!
+Haskell values.  Like `leftJoin` this particular formulation uses
+typeclasses so please put type signatures on everything in sight to
+minimize the number of confusing error messages!
 
 For example, for the 'twentiesAtAddress' query `runQuery` would have
 the following type:
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -5,6 +5,11 @@
 you want to use Haskell to write typesafe and composable code to query
 a Postgres database.
 
+> "Opaleye really is great. You've managed to bring what is so
+wonderful about relational databases and give it type safety and
+composition (i.e. what is wonderful about Haskell)" &ndash; Daniel
+Patterson, [Position Development](http://www.positiondev.com/)
+
 Opaleye allows you to define your database tables and write queries
 against them in Haskell code, and aims to be typesafe in the sense
 that if your code compiles then the generated SQL query will not fail
diff --git a/TODO.md b/TODO.md
--- a/TODO.md
+++ b/TODO.md
@@ -21,7 +21,7 @@
 
 * Make the code generation neater
 * Make VALUES work with more, type checked, value types
-* Product-valued case statements
+* Product-valued case statements and (.==)
 * Make the test database parameters more easily configurable
 * Randomised testing in a QuickCheck style
 * distinct, union and aggregate can be made to work with QueryArr
diff --git a/Test/Test.hs b/Test/Test.hs
--- a/Test/Test.hs
+++ b/Test/Test.hs
@@ -124,6 +124,10 @@
 table4 :: O.Table (Column O.PGInt4, Column O.PGInt4) (Column O.PGInt4, Column O.PGInt4)
 table4 = twoIntTable "table4"
 
+tableKeywordColNames :: O.Table (Column O.PGInt4, Column O.PGInt4)
+                                (Column O.PGInt4, Column O.PGInt4)
+tableKeywordColNames = O.Table "keywordtable" (PP.p2 (O.required "column", O.required "where"))
+
 table1Q :: Query (Column O.PGInt4, Column O.PGInt4)
 table1Q = O.queryTable table1
 
@@ -174,13 +178,27 @@
 table4columndata :: [(Column O.PGInt4, Column O.PGInt4)]
 table4columndata = table4dataG
 
-dropAndCreateTable :: String -> PGS.Query
-dropAndCreateTable t = String.fromString ("DROP TABLE IF EXISTS " ++ t ++ ";"
-                                          ++ "CREATE TABLE " ++ t
-                                          ++ " (column1 integer, column2 integer);")
+dropAndCreateTable :: (String, [String]) -> PGS.Query
+dropAndCreateTable (t, cols) = String.fromString drop_
+  where drop_ = "DROP TABLE IF EXISTS " ++ t ++ ";"
+                ++ "CREATE TABLE " ++ t
+                ++ " (" ++ commas cols ++ ");"
+        integer c = ("\"" ++ c ++ "\"" ++ " integer")
+        commas = L.intercalate "," . map integer
+        
+type Table_ = (String, [String])
 
+-- This should ideally be derived from the table definition above
+columns2 :: String -> Table_
+columns2 t = (t, ["column1", "column2"])
+
+-- This should ideally be derived from the table definition above
+tables :: [Table_]
+tables = map columns2 ["table1", "table2", "table3", "table4"]
+         ++ [("keywordtable", ["column", "where"])]
+
 dropAndCreateDB :: PGS.Connection -> IO ()
-dropAndCreateDB conn = mapM_ execute ["table1", "table2", "table3", "table4"]
+dropAndCreateDB conn = mapM_ execute tables
   where execute = PGS.execute_ conn . dropAndCreateTable
 
 type Test = PGS.Connection -> IO Bool
@@ -455,7 +473,15 @@
         expectedR :: [Int]
         expectedR = [-1]
 
+testKeywordColNames :: Test
+testKeywordColNames conn = do
+  let q :: IO [(Int, Int)]
+      q = O.runQuery conn (O.queryTable tableKeywordColNames)
+  _ <- q
+  return True
 
+  
+
 allTests :: [Test]
 allTests = [testSelect, testProduct, testRestrict, testNum, testDiv, testCase,
             testDistinct, testAggregate, testAggregateProfunctor,
@@ -464,7 +490,8 @@
             testDoubleDistinct, testDoubleAggregate, testDoubleLeftJoin,
             testDoubleValues, testDoubleUnionAll,
             testLeftJoin, testLeftJoinNullable, testThreeWayProduct, testValues,
-            testValuesEmpty, testUnionAll, testTableFunctor, testUpdate
+            testValuesEmpty, testUnionAll, testTableFunctor, testUpdate,
+            testKeywordColNames
            ]
 
 main :: IO ()
diff --git a/opaleye.cabal b/opaleye.cabal
--- a/opaleye.cabal
+++ b/opaleye.cabal
@@ -1,5 +1,5 @@
 name:            opaleye
-version:         0.3
+version:         0.3.1
 synopsis:        An SQL-generating DSL targeting PostgreSQL
 description:     An SQL-generating DSL targeting PostgreSQL.  Allows
                  Postgres queries to be written within Haskell in a
@@ -22,16 +22,20 @@
 library
   hs-source-dirs: src
   build-depends:
-      base                >= 4       && < 5
+      -- attoparsec can be removed once postgresql-simple patch in
+      -- Internal.RunQuery is merged upstream
+      attoparsec          >= 0.10.3  && < 0.13
+    , base                >= 4       && < 5
+    , case-insensitive    >= 1.2     && < 1.3
     , contravariant       >= 0.4.4   && < 1.3
     , old-locale          >= 1.0     && < 1.1
-    , postgresql-simple   >= 0.3     && < 0.5
+    , postgresql-simple   >= 0.4.8.0 && < 0.5
     , pretty              >= 1.1.1.0 && < 1.2
     , product-profunctors >= 0.5     && < 0.7
     , profunctors         >= 4.0     && < 4.4
-    , semigroups          >= 0.13    && < 0.16
+    , semigroups          >= 0.13    && < 0.17
     , text                >= 0.11    && < 1.3
-    , transformers        >= 0.3     && < 0.4
+    , transformers        >= 0.3     && < 0.5
     , time                >= 1.4     && < 1.5
     , uuid                >= 1.3     && < 1.4
   exposed-modules: Opaleye,
@@ -92,7 +96,8 @@
   main-is: Main.hs
   other-modules: TutorialAdvanced,
                  TutorialBasic,
-                 TutorialManipulation
+                 TutorialManipulation,
+                 DefaultExplanation
   hs-source-dirs: Doc/Tutorial
   build-depends:
     base >= 4 && < 5,
diff --git a/src/Opaleye/Internal/Binary.hs b/src/Opaleye/Internal/Binary.hs
--- a/src/Opaleye/Internal/Binary.hs
+++ b/src/Opaleye/Internal/Binary.hs
@@ -30,9 +30,12 @@
                  -> (columns, columns) -> f columns'
 runBinaryspec (Binaryspec b) = PM.packmap b
 
+binaryspecColumn :: Binaryspec (Column a) (Column a)
+binaryspecColumn = Binaryspec (PM.PackMap (\f (Column e, Column e')
+                                           -> fmap Column (f (e, e'))))
+
 instance Default Binaryspec (Column a) (Column a) where
-  def = Binaryspec (PM.PackMap (\f (Column e, Column e')
-                                -> fmap Column (f (e, e'))))
+  def = binaryspecColumn
 
 -- {
 
diff --git a/src/Opaleye/Internal/HaskellDB/Sql/Print.hs b/src/Opaleye/Internal/HaskellDB/Sql/Print.hs
--- a/src/Opaleye/Internal/HaskellDB/Sql/Print.hs
+++ b/src/Opaleye/Internal/HaskellDB/Sql/Print.hs
@@ -20,8 +20,9 @@
                                SqlUpdate(..))
 
 import Data.List (intersperse)
-import Text.PrettyPrint.HughesPJ (Doc, (<+>), ($$), (<>), comma, empty, equals,
-                                  hcat, hsep, parens, punctuate, text, vcat)
+import Text.PrettyPrint.HughesPJ (Doc, (<+>), ($$), (<>), comma, doubleQuotes,
+                                  empty, equals, hcat, hsep, parens, punctuate,
+                                  text, vcat)
 
 
 ppWhere :: [SqlExpr] -> Doc
@@ -74,8 +75,13 @@
       <+> parens (commaV ppColumn names)
       $$ text "VALUES" <+> parens (commaV ppSqlExpr values)
 
+-- If we wanted to make the SQL slightly more readable this would be
+-- one easy place to do it.  Currently we wrap all column references
+-- in double quotes in case they are keywords.  However, we should be
+-- sure that any column names we generate ourselves are not keywords,
+-- so we only need to double quote base table column names.
 ppColumn :: SqlColumn -> Doc
-ppColumn (SqlColumn s) = text s
+ppColumn (SqlColumn s) = doubleQuotes (text s)
 
 
 ppSqlExpr :: SqlExpr -> Doc
diff --git a/src/Opaleye/Internal/RunQuery.hs b/src/Opaleye/Internal/RunQuery.hs
--- a/src/Opaleye/Internal/RunQuery.hs
+++ b/src/Opaleye/Internal/RunQuery.hs
@@ -8,12 +8,13 @@
 import           Database.PostgreSQL.Simple.FromField (FieldParser, FromField,
                                                        fromField)
 import           Database.PostgreSQL.Simple.FromRow (fieldWith)
+import           Database.PostgreSQL.Simple.Types (fromPGArray)
 
 import           Opaleye.Column (Column)
 import           Opaleye.Internal.Column (Nullable)
 import qualified Opaleye.Column as C
 import qualified Opaleye.Internal.Unpackspec as U
-import           Opaleye.PGTypes as T
+import qualified Opaleye.PGTypes as T
 
 import qualified Data.Profunctor as P
 import           Data.Profunctor (dimap)
@@ -21,12 +22,33 @@
 import           Data.Profunctor.Product (empty, (***!))
 import qualified Data.Profunctor.Product.Default as D
 
+import qualified Data.CaseInsensitive as CI
 import qualified Data.Text as ST
 import qualified Data.Text.Lazy as LT
 import qualified Data.Time as Time
 import           Data.UUID (UUID)
 import           GHC.Int (Int64)
 
+-- { Only needed for annoying postgresql-simple patch below
+
+import           Control.Applicative ((<$>))
+import           Database.PostgreSQL.Simple.FromField
+  (Field, typoid, typeOid, typelem, TypeInfo,
+   ResultError(UnexpectedNull, ConversionFailed, Incompatible),
+   typdelim, typeInfo, returnError, Conversion)
+import           Database.PostgreSQL.Simple.Types (PGArray(PGArray))
+import           Data.Attoparsec.ByteString.Char8 (Parser, parseOnly)
+import qualified Database.PostgreSQL.Simple.TypeInfo as TI
+import qualified Database.PostgreSQL.Simple.Arrays as Arrays
+import           Database.PostgreSQL.Simple.Arrays (array, fmt)
+import           Data.String (fromString)
+import           Data.Typeable (Typeable)
+
+-- }
+
+-- We introduce 'QueryRunnerColumn' which is *not* a Product
+-- Profunctor because it is the only way I know of to get the instance
+-- generation to work for non-Nullable and Nullable types at once.
 data QueryRunnerColumn coltype haskell =
   QueryRunnerColumn (U.Unpackspec (Column coltype) ()) (FieldParser haskell)
 
@@ -104,6 +126,22 @@
 instance QueryRunnerColumnDefault T.PGTime Time.TimeOfDay where
   queryRunnerColumnDefault = fieldQueryRunnerColumn
 
+instance QueryRunnerColumnDefault T.PGCitext (CI.CI ST.Text) where
+  queryRunnerColumnDefault = fieldQueryRunnerColumn
+
+instance QueryRunnerColumnDefault T.PGCitext (CI.CI LT.Text) where
+  queryRunnerColumnDefault = fieldQueryRunnerColumn
+
+-- No CI String instance since postgresql-simple doesn't define FromField (CI String)
+
+arrayColumn :: Column (T.PGArray a) -> Column a
+arrayColumn = C.unsafeCoerce
+
+instance (Typeable b, QueryRunnerColumnDefault a b) =>
+         QueryRunnerColumnDefault (T.PGArray a) [b] where
+  queryRunnerColumnDefault = QueryRunnerColumn (P.lmap arrayColumn c) ((fmap . fmap . fmap) fromPGArray (arrayFieldParser f))
+    where QueryRunnerColumn c f = queryRunnerColumnDefault
+
 -- }
 
 -- Boilerplate instances
@@ -123,5 +161,36 @@
 instance PP.ProductProfunctor QueryRunner where
   empty = PP.defaultEmpty
   (***!) = PP.defaultProfunctorProduct
+
+-- }
+
+-- { Annoying postgresql-simple patch.  Delete this when it is merged upstream.
+
+arrayFieldParser :: Typeable a => FieldParser a -> FieldParser (PGArray a)
+arrayFieldParser
+    fieldParser f mdat = do
+        info <- typeInfo f
+        case info of
+          TI.Array{} ->
+              case mdat of
+                Nothing  -> returnError UnexpectedNull f ""
+                Just dat -> do
+                   case parseOnly (fromArray fieldParser info f) dat of
+                     Left  err  -> returnError ConversionFailed f err
+                     Right conv -> PGArray <$> conv
+          _ -> returnError Incompatible f ""
+
+fromArray :: FieldParser a -> TypeInfo -> Field -> Parser (Conversion [a])
+fromArray fieldParser typeInfo f = sequence . (parseIt <$>) <$> array delim
+  where
+    delim = typdelim (typelem typeInfo)
+    fElem = f{ typeOid = typoid (typelem typeInfo) }
+
+    parseIt item =
+        fieldParser f' $ if item' == fromString "NULL" then Nothing else Just item'
+      where
+        item' = fmt delim item
+        f' | Arrays.Array _ <- item = f
+           | otherwise              = fElem
 
 -- }
diff --git a/src/Opaleye/Join.hs b/src/Opaleye/Join.hs
--- a/src/Opaleye/Join.hs
+++ b/src/Opaleye/Join.hs
@@ -14,7 +14,12 @@
 
 import qualified Data.Profunctor.Product.Default as D
 
--- | Example specialization:
+-- | @leftJoin@'s use of the 'D.Default' typeclass means that the
+-- compiler will have trouble inferring types.  It is strongly
+-- recommended that you provide full type signatures when using
+-- @leftJoin@.
+--
+-- Example specialization:
 --
 -- @
 -- leftJoin :: Query (Column a, Column b)
diff --git a/src/Opaleye/Manipulation.hs b/src/Opaleye/Manipulation.hs
--- a/src/Opaleye/Manipulation.hs
+++ b/src/Opaleye/Manipulation.hs
@@ -110,6 +110,10 @@
                                        .:. arrangeInsertReturningSql u
   where IRQ.QueryRunner _ rowParser = qr
 
+-- | @runInsertReturning@'s use of the 'D.Default' typeclass means that the
+-- compiler will have trouble inferring types.  It is strongly
+-- recommended that you provide full type signatures when using
+-- @runInsertReturning@.
 runInsertReturning :: (D.Default RQ.QueryRunner returned haskells,
                        D.Default U.Unpackspec returned returned)
                       => PGS.Connection
diff --git a/src/Opaleye/Operators.hs b/src/Opaleye/Operators.hs
--- a/src/Opaleye/Operators.hs
+++ b/src/Opaleye/Operators.hs
@@ -69,3 +69,6 @@
 
 upper :: Column T.PGText -> Column T.PGText
 upper = C.unOp HPQ.OpUpper
+
+like :: Column T.PGText -> Column T.PGText -> Column T.PGBool
+like = C.binOp HPQ.OpLike
diff --git a/src/Opaleye/PGTypes.hs b/src/Opaleye/PGTypes.hs
--- a/src/Opaleye/PGTypes.hs
+++ b/src/Opaleye/PGTypes.hs
@@ -7,6 +7,7 @@
 
 import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
 
+import qualified Data.CaseInsensitive as CI
 import qualified Data.Text as SText
 import qualified Data.Text.Lazy as LText
 import qualified Data.Time as Time
@@ -28,6 +29,8 @@
 data PGTimestamp
 data PGTimestamptz
 data PGUuid
+data PGCitext
+data PGArray a
 
 instance C.PGNum PGFloat8 where
   pgFromInteger = pgDouble . fromInteger
@@ -91,3 +94,12 @@
 
 -- "We recommend not using the type time with time zone"
 -- http://www.postgresql.org/docs/8.3/static/datatype-datetime.html
+
+
+pgCiStrictText :: CI.CI SText.Text -> Column PGCitext
+pgCiStrictText = literalColumn . HPQ.StringLit . SText.unpack . CI.original
+
+pgCiLazyText :: CI.CI LText.Text -> Column PGCitext
+pgCiLazyText = literalColumn . HPQ.StringLit . LText.unpack . CI.original
+
+-- No CI String instance since postgresql-simple doesn't define FromField (CI String)
diff --git a/src/Opaleye/RunQuery.hs b/src/Opaleye/RunQuery.hs
--- a/src/Opaleye/RunQuery.hs
+++ b/src/Opaleye/RunQuery.hs
@@ -17,7 +17,12 @@
 import qualified Data.Profunctor as P
 import qualified Data.Profunctor.Product.Default as D
 
--- | Example type specialization:
+-- | @runQuery@'s use of the 'D.Default' typeclass means that the
+-- compiler will have trouble inferring types.  It is strongly
+-- recommended that you provide full type signatures when using
+-- @runQuery@.
+--
+-- Example type specialization:
 --
 -- @
 -- runQuery :: Query (Column 'Opaleye.PGTypes.PGInt4', Column 'Opaleye.PGTypes.PGText') -> IO [(Column Int, Column String)]
