<div><br></div>Ok,  Bas van Dijk has done some preliminary work in adding support for PostgreSQL&#39;s array types to postgresql-simple,  and I have some questions about arrays and types that I&#39;m hoping Jeff Davis can answer.   Here&#39;s a link, and a simple experiment in psql:<div>
<br></div><div><a href="https://github.com/basvandijk/postgresql-simple/commit/eb04ca39c5c22e3f4d083ba4986ab9e8339ed7d1">https://github.com/basvandijk/postgresql-simple/commit/eb04ca39c5c22e3f4d083ba4986ab9e8339ed7d1</a><br>
<br><br><font face="courier new, monospace">=&gt; create table strings (x text);<br>=&gt; insert into strings values (&#39;foo&#39;,&#39;bar&#39;,&#39;baz&#39;,&#39;hello world&#39;,&#39;goodbye cruel world&#39;);<br>=&gt; select array_agg(x) from strings group by x like (&#39;% %&#39;);<br>
               array_agg               <br>---------------------------------------<br> {foo,bar,baz}<br> {&quot;hello world&quot;,&quot;goodbye cruel world&quot;}<br>(2 rows)<br></font><br><br>So far so good,  but what if we try creating an array of arrays?<br>
<br><br><font face="courier new, monospace">=&gt; select array_agg(*) from (select array_agg(x) from strings group by x like (&#39;% %&#39;)) q;<br>ERROR:  function array_agg() does not exist<br>LINE 1: select array_agg(*) from (select array_agg(x) from strings g...<br>
               ^<br>HINT:  No function matches the given name and argument types. You might need to add explicit type casts.<br></font><br>Now,  presumably,  postgresql does actually support arrays of arrays,   but I&#39;m guessing that you need to create the array of array of string type before you can actually run this query...<br>
<br>The reason I ask is that Bas van Dijk has done some work on adding support for arrays to postgresql-simple.   And he&#39;s modified the type cache from TypeOID -&gt;  IO  TypeName to become a TypeOID -&gt; IO TypeInfo,  where the TypeInfo type is defined as follows:<br>
<br><font face="courier new, monospace">data NamedOid = NamedOid { typoid  :: !PQ.Oid<br>                         , typname :: !ByteString<br>                         } deriving Show<br><br>data TypeInfo = TypeInfo { typ     :: !NamedOid<br>
                         , typelem :: !(Maybe NamedOid)<br>                         } deriving Show<br></font><br>I think this is a perfectly reasonable first attempt,  but I don&#39;t think it&#39;s correct,  because I&#39;m pretty sure that PostgreSQL does actually support arrays of arrays if you know what you are doing.   So I think that TypeInfo needs to look something more like <div>
<br></div><div><div><span style="font-family:&#39;courier new&#39;,monospace">data TypeInfo = Plain { typ     :: !NamedOid </span><span style="font-family:&#39;courier new&#39;,monospace">}</span></div><div><span style="font-family:&#39;courier new&#39;,monospace">              | Array { typ     :: !NamedOid</span></div>
<div><span style="font-family:&#39;courier new&#39;,monospace">                      , typelem :: !TypeInfo } </span></div><div><span style="font-family:&#39;courier new&#39;,monospace">                deriving Show</span><br style="font-family:&#39;courier new&#39;,monospace">
</div></div><div><span style="font-family:&#39;courier new&#39;,monospace"><br></span></div><div>The real issue here is one dealing with purity and effects:   In some sense,  Bas&#39;s first attempt carries the same information,  but you might need to do some IO in order to retrieve it. (Though this assumes that one can query the type cache directly,  which is something I should probably add anyway...)  But the fromField method,  which is is the most likely consumer of this information,  isn&#39;t allowed to do IO.   So I think we really want to change this type.</div>
<div><br></div><div>Also,  this type makes it more natural to add support for the new range types available in PostgreSQL 9.2.    (Which Jeff is largely responsible for,  by the way...)    The extended TypeInfo might look like this:</div>
<div><br></div><div><div><span style="font-family:&#39;courier new&#39;,monospace">data TypeInfo = Plain { typ     :: !NamedOid </span><span style="font-family:&#39;courier new&#39;,monospace">}</span></div><div><span style="font-family:&#39;courier new&#39;,monospace">              | Array { typ     :: !NamedOid</span></div>
<div><span style="font-family:&#39;courier new&#39;,monospace">                      , typelem :: !TypeInfo } </span></div><div><span style="font-family:&#39;courier new&#39;,monospace">              | Range { typ     :: !NamedOid</span></div>
<div><span style="font-family:&#39;courier new&#39;,monospace">                      , typelem :: !TypeInfo } </span></div><div><span style="font-family:&#39;courier new&#39;,monospace">                deriving Show</span><br style="font-family:&#39;courier new&#39;,monospace">
</div><div><span style="font-family:&#39;courier new&#39;,monospace"><br></span></div>So,  I think that&#39;s enough issues to talk about for the time being.</div></div><div><br></div><div>Best,</div><div>Leon</div>