<literal>PUBLIC</literal> for newly created functions
(see <xref linkend="ddl-priv"/> for more
information). Frequently you will wish to restrict use of a security
definer function to only some users. To do that, you must revoke
the default <literal>PUBLIC</literal> privileges and then grant execute
privilege selectively. To avoid having a window where the new function
is accessible to all, create it and set the privileges within a single
transaction. For example:
</para>
<programlisting>
BEGIN;
CREATE FUNCTION check_password(uname TEXT, pass TEXT) ... SECURITY DEFINER;
REVOKE ALL ON FUNCTION check_password(uname TEXT, pass TEXT) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION check_password(uname TEXT, pass TEXT) TO admins;
COMMIT;
</programlisting>
</refsect1>
<refsect1 id="sql-createfunction-compat">
<title>Compatibility</title>
<para>
A <command>CREATE FUNCTION</command> command is defined in the SQL
standard. The <productname>PostgreSQL</productname> implementation can be
used in a compatible way but has many extensions. Conversely, the SQL
standard specifies a number of optional features that are not implemented
in <productname>PostgreSQL</productname>.
</para>
<para>
The following are important compatibility issues:
<itemizedlist>
<listitem>
<para>
<literal>OR REPLACE</literal> is a PostgreSQL extension.
</para>
</listitem>
<listitem>
<para>
For compatibility with some other database systems, <replaceable
class="parameter">argmode</replaceable> can be written either before or
after <replaceable class="parameter">argname</replaceable>. But only
the first way is standard-compliant.
</para>
</listitem>
<listitem>
<para>
For parameter defaults, the SQL standard specifies only the syntax with
the <literal>DEFAULT</literal> key word. The syntax with
<literal>=</literal> is used in T-SQL and Firebird.
</para>
</listitem>
<listitem>
<para>
The <literal>SETOF</literal> modifier is a PostgreSQL extension.
</para>
</listitem>
<listitem>
<para>
Only <literal>SQL</literal> is standardized as a language.
</para>
</listitem>
<listitem>
<para>
All other attributes except <literal>CALLED ON NULL INPUT</literal> and
<literal>RETURNS NULL ON NULL INPUT</literal> are not standardized.
</para>
</listitem>
<listitem>
<para>
For the body of <literal>LANGUAGE SQL</literal> functions, the SQL
standard only specifies the <replaceable>sql_body</replaceable> form.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Simple <literal>LANGUAGE SQL</literal> functions can be written in a way
that is both standard-conforming and portable to other implementations.
More complex functions using advanced features, optimization attributes, or
other languages will necessarily be specific to PostgreSQL in a significant
way.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-alterfunction"/></member>
<member><xref linkend="sql-dropfunction"/></member>
<member><xref linkend="sql-grant"/></member>
<member><xref linkend="sql-load"/></member>
<member><xref linkend="sql-revoke"/></member>
</simplelist>
</refsect1>
</refentry>