<!-- doc/src/sgml/restrictions.sgml -->

<sect1 id="restrictions">
 <title>Restrictions</title>

 <para>
  This section descibes current restrictions of <productname>Pgpool-II</productname>.

  <variablelist>

   <varlistentry>
    <term>Functionality of PostgreSQL</term>
    <listitem>
     <para>
       If you use <function>pg_terminate_backend()</function> to stop
       a backend, this will trigger a failover.  The reason why this
       happens is that <productname>PostgreSQL</productname> sends
       exactly the same message for a terminated backend as for a full
       postmaster shutdown.  There is no workaround prior of version
       3.6. From version 3.6, this limitation has been mitigated. If
       the argument to the function (that is a process id) is a
       constant, you can safely use the function. In extended protocol
       mode, you cannot use the function though.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term>Authentication/Access Controls</term>
    <listitem>
      <para>
	In the replication mode or master/slave mode, trust, clear
        text password, and pam methods are supported. md5 in also
        supported since <productname>Pgpool-II</productname> 3.0.  md5
        is supported by using a authencitaion file <filename>pool_passwd</filename>.
        <filename>pool_passwd</filename> is default name of the
        authentication file. Here are the
        steps to enable md5 authentication:
      </para>

      <orderedlist>

	<listitem>
	  <para>
	    Login as the database's operating system user and type:
	    <programlisting>
            pg_md5 --md5auth --username=<literal>your_username</literal> <literal>your_passwd</literal>
	    </programlisting>
            user name and md5 encrypted password are registered into
            pool_passwd.  If pool_passwd does not exist yet, pg_md5
            command will automatically create it for you.  The format
            of pool_passwd
            is <literal>username:encrypted_passwd</literal>.
	  </para>
	</listitem>

	<listitem>
	  <para>
	    You also need to add an appropriate md5 entry to
            pool_hba.conf.  See <xref linkend="auth-pool-hba-conf"> for more details.
	  </para>
	</listitem>

	<listitem>
	  <para>
            Please note that the user name and password must be
            identical to those registered
            in <productname>PostgreSQL</productname>.
	  </para>
	</listitem>

	<listitem>
	  <para>
            After changing md5 password (in both pool_passwd and
            PostgreSQL of course), you need to
            execute <application>pgpool reload</application>.
	  </para>
	</listitem>
      </orderedlist>

    </listitem>
   </varlistentry>

   <varlistentry>
    <term>Large objects</term>
    <listitem>
      <para>
	In streaming replication
	mode, <productname>Pgpool-II</productname> supports large
	objects.
      </para>
      <para>
	In native replication
	mode, <productname>Pgpool-II</productname> supports large
	objects if the backend
	is <productname>PostgreSQL</productname> 8.1 or later.  For
	this, you need to enable lobj_lock_table directive
	in <filename>pgpool.conf</filename>.  Large object replication
	using backend function <function>lo_import</function> is not
	supported, however.
      </para>
      <para>
	In other mode, including Slony mode, large
	objects are not supported.
      </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term>Temporary tables</term>
    <listitem>
      <para>
	Creating/inserting/updating/deleting temporary tables are
	always executed on the master (primary) in master slave mode.
	SELECT on these tables is executed on master as well.  However
	if the temporary table name is used as a literal in SELECT,
	there's no way to detect it, and the SELECT will be load
	balanced.  That will trigger a "not found the table" error or
	will find another table having same name.  To avoid the
	problem, use /*NO LOAD BALANCE*/ SQL comment.
      </para>
      <para>
	Note that such literal table names used in queries to access
	system catalogs do cause problems described above.  psql's \d
	command produces such that query:
	<programlisting>
SELECT 't1'::regclass::oid;
	</programlisting>
	In such that case <productname>Pgpool-II</productname> always
	sends the query to master and will not cause the problem.
      </para>

      <para>
	Tables created by <command>CREATE TEMP TABLE</command> will be
	deleted at the end of the session by specifying DISCARD ALL in
	reset_query_list if you are using PostgreSQL 8.3 or later.
      </para>
      <para>
	For 8.2.x or earlier, tables created by <command>CREATE TEMP
	TABLE</command> will not be deleted after exiting a
	session. It is because of the connection pooling which, from
	PostgreSQL's backend point of view, keeps the session
	alive. To avoid this, you must explicitly drop the temporary
	tables by issuing <command>DROP TABLE</command>, or
	use <command>CREATE TEMP TABLE ... ON COMMIT DROP</command>
	inside the transaction block.
      </para>

    </listitem>
   </varlistentry>

   <varlistentry>
    <term>Functions, etc. In Native Replication mode</term>
    <listitem>
      <para>
	There is no guarantee that any data provided using a
	context-dependent mechanism (e.g. random number, transaction
	ID, OID, SERIAL, sequence), will be replicated correctly on
	multiple backends. For SERIAL, enabling insert_lock will help
	replicating data.  insert_lock also helps SELECT setval() and
	SELECT nextval().
      </para>
      <para>
	INSERT/UPDATE
	using <function>CURRENT_TIMESTAMP</function>, <function>CURRENT_DATE</function>,
	<function>now()</function> will be replicated
	correctly. INSERT/UPDATE for tables
	using <function>CURRENT_TIMESTAMP</function>, <function>CURRENT_DATE</function>,
	<function>now()</function> as their DEFAULT values will also
	be replicated correctly.  This is done by replacing those
	functions by constants fetched from master at query execution
	time.  There are a few limitations however:
      </para>
      <para>
	In <productname>Pgpool-II</productname> 3.0 or before, the
        calculation of temporal data in table default value is not
        accurate in some cases. For example, the following table
        definition:
	<programlisting>
CREATE TABLE rel1(
  d1 date DEFAULT CURRENT_DATE + 1
)
	</programlisting>
	is treated the same as:
	<programlisting>
CREATE TABLE rel1(
  d1 date DEFAULT CURRENT_DATE
)
	</programlisting>
	<productname>Pgpool-II</productname> 3.1 or later handles
	these cases correctly.  Thus the column "d1" will have
	tomorrow as the default value.  However this enhancement does
	not apply if extended protocols (used in JDBC, PHP PDO for
	example) or PREPARE are used.
      </para>
      <para>
	Please note that if the column type is not a temporal one,
	rewriting is not performed. Such example:
	<programlisting>
foo bigint default (date_part('epoch'::text,('now'::text)::timestamp(3) with time zone) * (1000)::double precision)
	</programlisting>
	Suppose we have the following table:
	<programlisting>
CREATE TABLE rel1(
  c1 int,
  c2 timestamp default now()
)
	</programlisting>
	We can replicate
	<programlisting>
INSERT INTO rel1(c1) VALUES(1)
	</programlisting>

    since this turn into

	<programlisting>
INSERT INTO rel1(c1, c2) VALUES(1, '2009-01-01 23:59:59.123456+09')
	</programlisting>

    However,
	<programlisting>
INSERT INTO rel1(c1) SELECT 1
	</programlisting>
    cannot to be transformed, thus cannot be properly replicated in the current implementation.
    Values will still be inserted, with no transformation at all.
      </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term>SQL type commands</term>
    <listitem>
      <para>
	<link linkend="sql-commands">SQL type commands</link> cannot
	be used in extended query mode.
      </para>
    </listitem>
   </varlistentry>

  </variablelist>
 </para>
</sect1>
