title: pg_restore: can't import data if table has a constraint with a function calling another function
body: <p>In PostgreSQL using only <code>public</code> schema, data in tables that use in check constraints functions that invoke other functions does not get imported with <code>pg_restore</code> after it was dumped with <code>pg_dump</code>. But if functions in check constraints do not invoke other functions, data is correctly imported.</p>
  
  <p>I have noted this behavior after minor upgrading from 9.3.22 to 9.3.23 and from 9.4.16 to 9.4.17; in 9.3.22 and 9.4.17 it worked fine.</p>
  
  <p>I understand is due to <a href="https://bucardo.org/postgres_all_versions.html#version_9.3.22" rel="nofollow noreferrer">changes in search_path</a>:</p>
  
  <blockquote>
    <p>Avoid use of insecure search_path settings in pg_dump and other client
    programs (Noah Misch, Tom Lane)</p>
    
    <p>pg_dump, pg_upgrade, vacuumdb and other PostgreSQL-provided
    applications were themselves vulnerable to the type of hijacking
    described in the previous changelog entry; since these applications
    are commonly run by superusers, they present particularly attractive
    targets. To make them secure whether or not the installation as a
    whole has been secured, modify them to include only the pg_catalog
    schema in their search_path settings. Autovacuum worker processes now
    do the same, as well.</p>
    
    <p>In cases where user-provided functions are indirectly executed by
    these programs — for example, user-provided functions in index
    expressions — the tighter search_path may result in errors, which will
    need to be corrected by adjusting those user-provided functions to not
    assume anything about what search path they are invoked under. That
    has always been good practice, but now it will be necessary for
    correct behavior. (CVE-2018-1058 or CVE-2018-1058)</p>
  </blockquote>
  
  <p>Still it's unclear to me why having one level public functions is allowed but it is not those functions to invoke other ones.</p>
  
  <p>For example, having this structure and data:</p>
  
  <pre><code>CREATE OR REPLACE FUNCTION is_even(n integer) RETURNS boolean AS $BODY$ 
  BEGIN
    return n%2 = 0;  
  END ; $BODY$  LANGUAGE plpgsql;
  
  CREATE OR REPLACE FUNCTION is_even_positive(n integer) RETURNS boolean AS $BODY$ 
  BEGIN
    return is_even(n) and n &gt; 0;  
  END ; $BODY$  LANGUAGE plpgsql;
  
  
  CREATE TABLE test_check (
    n integer
    CONSTRAINT even_chk CHECK (is_even(n)));
  
  CREATE TABLE test_check2(
    n integer
    CONSTRAINT even_positive_chk CHECK (is_even_positive(n)));
  
  insert into test_check values (2);
  insert into test_check values (-2);
  insert into test_check2 values (2);
  </code></pre>
  
  <p>Exporting it with:</p>
  
  <pre><code>pg_dump -h localhost -p 5432  -F c -b -v -f test.dmp test -U test
  </code></pre>
  
  <p>And importing it in a new database:</p>
  
  <pre><code>$ pg_restore -d test2 -U test -v test.dmp -h localhost
  pg_restore: connecting to database for restore
  pg_restore: creating SCHEMA "public"
  pg_restore: creating COMMENT "SCHEMA public"
  pg_restore: creating EXTENSION "plpgsql"
  pg_restore: creating COMMENT "EXTENSION plpgsql"
  pg_restore: creating FUNCTION "public.is_even(integer)"
  pg_restore: creating FUNCTION "public.is_even_positive(integer)"
  pg_restore: creating TABLE "public.test_check"
  pg_restore: creating TABLE "public.test_check2"
  pg_restore: processing data for table "public.test_check"
  pg_restore: processing data for table "public.test_check2"
  pg_restore: [archiver (db)] Error while PROCESSING TOC:
  pg_restore: [archiver (db)] Error from TOC entry 2035; 0 7784774 TABLE DATA test_check2 tad
  pg_restore: [archiver (db)] COPY failed for table "test_check2": ERROR:  function is_even(integer) does not exist
  LINE 1: SELECT is_even(n) and n &gt; 0
                 ^
  HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
  QUERY:  SELECT is_even(n) and n &gt; 0
  CONTEXT:  PL/pgSQL function public.is_even_positive(integer) line 3 at RETURN
  COPY test_check2, line 1: "2"
  pg_restore: creating ACL "SCHEMA public"
  WARNING: errors ignored on restore: 1
  </code></pre>
  
  <p>Note <code>test_check</code> table gets correctly imported with data whereas <code>test_check2</code> fails.</p>