<!--
doc/src/sgml/ref/create_foreign_data_wrapper.sgml
PostgreSQL documentation
-->

<refentry id="SQL-CREATEFOREIGNDATAWRAPPER">
 <refmeta>
  <refentrytitle>CREATE FOREIGN DATA WRAPPER</refentrytitle>
  <manvolnum>7</manvolnum>
  <refmiscinfo>SQL - Language Statements</refmiscinfo>
 </refmeta>

 <refnamediv>
  <refname>CREATE FOREIGN DATA WRAPPER</refname>
  <refpurpose>define a new foreign-data wrapper</refpurpose>
 </refnamediv>

 <indexterm zone="sql-createforeigndatawrapper">
  <primary>CREATE FOREIGN DATA WRAPPER</primary>
 </indexterm>

 <refsynopsisdiv>
<synopsis>
CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
    [ HANDLER <replaceable class="parameter">handler_function</replaceable> | NO HANDLER ]
    [ VALIDATOR <replaceable class="parameter">validator_function</replaceable> | NO VALIDATOR ]
    [ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] ) ]
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <command>CREATE FOREIGN DATA WRAPPER</command> creates a new
   foreign-data wrapper.  The user who defines a foreign-data wrapper
   becomes its owner.
  </para>

  <para>
   The foreign-data wrapper name must be unique within the database.
  </para>

  <para>
   Only superusers can create foreign-data wrappers.
  </para>
 </refsect1>

 <refsect1>
  <title>Parameters</title>

  <variablelist>
   <varlistentry>
    <term><replaceable class="parameter">name</replaceable></term>
    <listitem>
     <para>
      The name of the foreign-data wrapper to be created.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>HANDLER <replaceable class="parameter">handler_function</replaceable></literal></term>
    <listitem>
     <para><replaceable class="parameter">handler_function</replaceable> is the
      name of a previously registered function that will be called to
      retrieve the execution functions for foreign tables.
      The handler function must take no arguments, and
      its return type must be <type>fdw_handler</type>.
     </para>

     <para>
      It is possible to create a foreign-data wrapper with no handler
      function, but foreign tables using such a wrapper can only be declared,
      not accessed.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>VALIDATOR <replaceable class="parameter">validator_function</replaceable></literal></term>
    <listitem>
     <para><replaceable class="parameter">validator_function</replaceable> is the
      name of a previously registered function that will be called to
      check the generic options given to the foreign-data wrapper, as
      well as options for foreign servers and user mappings using the
      foreign-data wrapper.  If no validator function or <literal>NO
      VALIDATOR</literal> is specified, then options will not be
      checked at creation time.  (Foreign-data wrappers will possibly
      ignore or reject invalid option specifications at run time,
      depending on the implementation.)  The validator function must
      take two arguments: one of type <type>text[]</type>, which will
      contain the array of options as stored in the system catalogs,
      and one of type <type>oid</type>, which will be the OID of the
      system catalog containing the options. The return type is ignored;
      the function should report invalid options using the
      <function>ereport(ERROR)</function> function.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [, ... ] )</literal></term>
    <listitem>
     <para>
      This clause specifies options for the new foreign-data wrapper.
      The allowed option names and values are specific to each foreign
      data wrapper and are validated using the foreign-data wrapper's
      validator function.  Option names must be unique.
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   At the moment, the foreign-data wrapper functionality is rudimentary.
   There is no support for updating a foreign table, and optimization of
   queries is primitive (and mostly left to the wrapper, too).
  </para>

  <para>
   There is one built-in foreign-data wrapper validator function
   provided:
   <filename>postgresql_fdw_validator</filename>, which accepts
   options corresponding to <application>libpq</> connection
   parameters.
  </para>
 </refsect1>

 <refsect1>
  <title>Examples</title>

  <para>
   Create a useless foreign-data wrapper <literal>dummy</>:
<programlisting>
CREATE FOREIGN DATA WRAPPER dummy;
</programlisting>
  </para>

  <para>
   Create a foreign-data wrapper <literal>file</> with
   handler function <literal>file_fdw_handler</>:
<programlisting>
CREATE FOREIGN DATA WRAPPER file HANDLER file_fdw_handler;
</programlisting>
  </para>

  <para>
   Create a foreign-data wrapper <literal>mywrapper</> with some
   options:
<programlisting>
CREATE FOREIGN DATA WRAPPER mywrapper
    OPTIONS (debug 'true');
</programlisting></para>
 </refsect1>

 <refsect1>
  <title>Compatibility</title>

  <para>
   <command>CREATE FOREIGN DATA WRAPPER</command> conforms to ISO/IEC
   9075-9 (SQL/MED), with the exception that the <literal>HANDLER</literal>
   and <literal>VALIDATOR</literal> clauses are extensions and the standard
   clauses <literal>LIBRARY</literal> and <literal>LANGUAGE</literal>
   are not implemented in PostgreSQL.
  </para>

  <para>
   Note, however, that the SQL/MED functionality as a whole is not yet
   conforming.
  </para>
 </refsect1>

 <refsect1>
  <title>See Also</title>

  <simplelist type="inline">
   <member><xref linkend="sql-alterforeigndatawrapper"></member>
   <member><xref linkend="sql-dropforeigndatawrapper"></member>
   <member><xref linkend="sql-createserver"></member>
   <member><xref linkend="sql-createusermapping"></member>
  </simplelist>
 </refsect1>

</refentry>
