title: Postgresql array encoding in Doobie – text[] vs varying[]
body: <p>Suppose we have this postgresql schema:</p>
  <pre class="lang-sql prettyprint-override"><code>CREATE TABLE &quot;temp&quot; (id  int, fields text[]);
  INSERT INTO &quot;temp&quot; VALUES
    (1, array['abc', 'def']),
    (2, array['abc', 'def', 'jkl']),
    (3, array['abd', 'def']),
    (4, '{&quot;1{c}1&quot;, a}');
  </code></pre>
  <p>The following works in plain SQL, returning rows 1 and 2 (<code>@&gt;</code> is the &quot;contains&quot; operator in pg):</p>
  <pre class="lang-sql prettyprint-override"><code>SELECT id, fields FROM temp WHERE &quot;fields&quot; @&gt; '{def, abc}';
  </code></pre>
  <p>But the same in <a href="https://tpolecat.github.io/doobie/" rel="nofollow noreferrer">Doobie</a> (with its postgresql extension):</p>
  <pre class="lang-scala prettyprint-override"><code>import doobie._
  import doobie.implicits._
  import doobie.postgres.implicits._
  val searchTerms = List(&quot;def&quot;, &quot;abc&quot;)
  fr&quot;SELECT id, fields FROM temp WHERE fields @&gt; $searchTerms&quot;
  </code></pre>
  <p>Fails with:</p>
  <pre><code>org.postgresql.util.PSQLException: ERROR: operator does not exist: text[] @&gt; character varying[]
  Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
  </code></pre>
  <p>Casting the interpolated <code>searchTerms</code> value to <code>text[]</code> seems to solve the problem:</p>
  <pre class="lang-scala prettyprint-override"><code>val searchTerms = List(&quot;def&quot;, &quot;abc&quot;)
  fr&quot;SELECT id, fields FROM temp WHERE fields @&gt; CAST($searchTerms AS text[])&quot;
  </code></pre>
  <p>Similarly, I can change the type of the <code>fields</code> column from <code>text[]</code> to <code>varchar[]</code> in the database schema to avoid the cast, and that would also compile and return the correct rows.</p>
  <p>My main problem is that I don't know why Doobie behaves that way. I will probably run into this same issue again with custom types, so I need to understand why <code>$searchTerms</code> decodes into <code>varying[]</code> and not <code>text[]</code>, and what, if anything, I can do to change this behaviour so that I can keep the <code>text[]</code> column type and avoid the cast. I'm guessing there's probably an implicit instance somewhere controlling this, but I couldn't figure out what it is.</p>