<!-- $Header: /var/cvs/wg/jpugdoc/jpugdoc/slony/1.1.0/adminguide/schemadoc.xml.ja,v 1.1 2006/01/02 12:19:26 honda Exp $ -->






  <chapter id="schema"
           xreflabel="schemadoc">
    <title><!--Schema--> schemadoc</title>
    <para></para>


      <section id="table.sl-config-lock"
               xreflabel="sl_config_lock">
        <title id="table.sl-config-lock-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_config_lock</structname>
        </title>
 

        <para><!--
          This table exists solely to prevent overlapping execution of configuration change procedures and the resulting possible deadlocks.-->
Υơ֥Ϸ̤ȤƥǥåɥåȤʤ롢ѹμ¹Ԥνʣ򤱤ŪΤ¸ߤޤ

        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_config_lock</structname> ι
            </title>


            <varlistentry>
              <term><structfield>dummy</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

            </listitem>
          </varlistentry>

        </variablelist>










      </para>
    </section>

      <section id="table.sl-confirm"
               xreflabel="sl_confirm">
        <title id="table.sl-confirm-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_confirm</structname>
        </title>
 

        <para>
<!--
          Holds confirmation of replication events.  After a period of time, Slony removes old confirmed events from both this table and the sl_event table.
-->
         ץꥱݤγǧͭޤ֤ηв塢Slony ϤΥơ֥ sl_event ơ֥뤫Ťǧݤޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_confirm</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>con_origin</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

              <para>
<!--
                The ID # (from sl_node.no_id) of the source node for this event
 -->
                λݤФ륽ΡɤΡsl_node.no_id Ρ˼ֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>con_received</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>con_seqno</structfield></term>
              <listitem><para>
                <type>bigint</type>







              </para>

              <para>
                <!--The ID # for the event-->ݤμֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>con_timestamp</structfield></term>
              <listitem><para>
                <type>timestamp without time zone</type>





                <literal>DEFAULT (timeofday())::timestamp without time zone</literal>



              </para>

              <para>
                <!--When this event was confirmed-->λݤǧ줿
              </para>

            </listitem>
          </varlistentry>

        </variablelist>





        <variablelist>
          <title><!--Indexes on -->sl_confirm Υǥå</title>

          <varlistentry>
            <term>sl_confirm_idx1</term>
            <listitem><para>con_origin, con_received, con_seqno</para></listitem>
          </varlistentry>



          <varlistentry>
            <term>sl_confirm_idx2</term>
            <listitem><para>con_received, con_seqno</para></listitem>
          </varlistentry>

        </variablelist>








      </para>
    </section>

      <section id="table.sl-event"
               xreflabel="sl_event">
        <title id="table.sl-event-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_event</structname>
        </title>
 

        <para>
<!--
          Holds information about replication events.  After a period of time, Slony removes old confirmed events from both this table and the sl_confirm table.
-->
          ץꥱݤդƤξ¸ޤ֤ηв塢Slony ϤΥơ֥ sl_confirm ơ֥뤫Ťǧݤޤ         
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_event</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>ev_origin</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>













              </para>

              <para><!--
                The ID # (from sl_node.no_id) of the source node for this event-->
                λݤФ륽ΡɤΡsl_node.no_id Ρ˼ֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_seqno</structfield></term>
              <listitem><para>
                <type>bigint</type>


                <literal>PRIMARY KEY</literal>













              </para>

              <para>
                <!--The ID # for the event-->ݤμֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_timestamp</structfield></term>
              <listitem><para>
                <type>timestamp without time zone</type>







              </para>

              <para>
                <!--When this event record was created-->λݥ쥳ɤ줿
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_minxid</structfield></term>
              <listitem><para>
                <type>xxid</type>







              </para>

              <para>
                <!--Earliest XID on provider node for this event-->λݤФץХΡɾκǤ XID
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_maxxid</structfield></term>
              <listitem><para>
                <type>xxid</type>







              </para>

              <para>
                <!--Latest XID on provider node for this event-->λݤФץХΡɾκǿ XID
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_xip</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--List of XIDs, in order, that are part of this event-->λݤΰǤä XID Υꥹ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_type</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <programlisting>
                <!--The type of event this record is for.-->Υ쥳ɤ뤿λݤΥ
				SYNC			= <!--Synchronise-->Ʊ
				STORE_NODE		=
				ENABLE_NODE		=
				DROP_NODE		=
				STORE_PATH		=
				DROP_PATH		=
				STORE_LISTEN		=
				DROP_LISTEN		=
				STORE_SET		=
				DROP_SET		=
				MERGE_SET		=
				SET_ADD_TABLE		=
				SET_ADD_SEQUENCE	=
				STORE_TRIGGER		=
				DROP_TRIGGER		=
				MOVE_SET		=
				SET_DROP_TABLE		=
				SET_DROP_SEQUENCE	=
				SET_MOVE_TABLE		=
				SET_MOVE_SEQUENCE	=
				FAILOVER_SET		=
				SUBSCRIBE_SET		=
				ENABLE_SUBSCRIPTION	=
				UNSUBSCRIBE_SET		=
				DDL_SCRIPT		=
				ADJUST_SEQ		=
				RESET_CONFIG		=
                 </programlisting>
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_data1</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Data field containing an argument needed to process the event-->ݽɬפʰޤǡե
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_data2</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Data field containing an argument needed to process the event-->ݽɬפʰޤǡե
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_data3</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Data field containing an argument needed to process the event-->ݽɬפʰޤǡե
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_data4</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Data field containing an argument needed to process the event-->ݽɬפʰޤǡե
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_data5</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Data field containing an argument needed to process the event-->ݽɬפʰޤǡե
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_data6</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Data field containing an argument needed to process the event-->ݽɬפʰޤǡե
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_data7</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Data field containing an argument needed to process the event-->ݽɬפʰޤǡե
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ev_data8</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Data field containing an argument needed to process the event-->ݽɬפʰޤǡե
              </para>

            </listitem>
          </varlistentry>

        </variablelist>










      </para>
    </section>

      <section id="table.sl-listen"
               xreflabel="sl_listen">
        <title id="table.sl-listen-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_listen</structname>
        </title>
 

        <para>
<!--
          Indicates how nodes listen to events from other nodes in the Slony-I network.
-->
          Slony-I ͥåȥ¾ΥΡɤλݤɤΤ褦˴ƻ뤹뤫ؼޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_listen</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>li_origin</structfield></term>
              <listitem><para>
                <type>integer</type>






                <literal>PRIMARY KEY</literal>












                <literal>REFERENCES</literal> <xref linkend="table.sl-node"/>




              </para>

              <para>
<!--
                The ID # (from sl_node.no_id) of the node this listener is operating on
-->
                δƻʥꥹʡˤưƤΡɤΡsl_node.no_id Ρ˼ֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>li_provider</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>


















                <literal>REFERENCES</literal> <xref linkend="table.sl-path"/>


              </para>

              <para>
<!--
                The ID # (from sl_node.no_id) of the source node for this listening event
-->
                δƻݤФ륽ΡɤΡsl_node.no_id Ρ˼ֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>li_receiver</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>


















                <literal>REFERENCES</literal> <xref linkend="table.sl-path"/>


              </para>

              <para>
<!--
                The ID # (from sl_node.no_id) of the target node for this listening event
-->
                δƻݤФ륿åȥΡɡsl_node.no_id Ρ˼ֹ̻
              </para>

            </listitem>
          </varlistentry>

        </variablelist>










      </para>
    </section>

      <section id="table.sl-log-1"
               xreflabel="sl_log_1">
        <title id="table.sl-log-1-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_log_1</structname>
        </title>
 

        <para>
<!--
          Stores each change to be propagated to subscriber nodes
-->
          ɥΡɤؤŤ٤ˤ줾ѹ¸ޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_log_1</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>log_origin</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

              <para>
                <!--Origin node from which the change came-->ѹ륪ꥸΡ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_xid</structfield></term>
              <listitem><para>
                <type>xxid</type>







              </para>

              <para>
                <!--Transaction ID on the origin node-->ꥸΡɾΥȥ󥶥̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_tableid</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

              <para>
<!--
                The table ID (from sl_table.tab_id) that this log entry is to affect
-->
                Υȥ꤬Ѥڤܤsl_table.tab_id Ρ˥ơ֥뼱̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_actionseq</structfield></term>
              <listitem><para>
                <type>bigint</type>







              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_cmdtype</structfield></term>
              <listitem><para>
                <type>character(1)</type>







              </para>

              <para>
<!--
                Replication action to take. U = Update, I = Insert, D = DELETE
-->
                ץꥱư U =  I =  D = 
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_cmddata</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--The data needed to perform the log action-->ư¹ԤΤɬפʥǡ
              </para>

            </listitem>
          </varlistentry>

        </variablelist>










      </para>
    </section>

      <section id="table.sl-log-2"
               xreflabel="sl_log_2">
        <title id="table.sl-log-2-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_log_2</structname>
        </title>
 

        <para>
<!--
          Stores each change to be propagated to subscriber nodes
-->
          ɥΡɤؤŤ٤ˤ줾ѹ¸ޤ   
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_log_2</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>log_origin</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

              <para>
                <!--Origin node from which the change came-->ѹ륪ꥸΡ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_xid</structfield></term>
              <listitem><para>
                <type>xxid</type>







              </para>

              <para>
                <!--Transaction ID on the origin node-->ꥸΡɾΥȥ󥶥̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_tableid</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

              <para>
<!--
                The table ID (from sl_table.tab_id) that this log entry is to affect
--> 
                Υȥ꤬Ѥڤܤsl_table.tab_id Ρ˥ơ֥뼱̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_actionseq</structfield></term>
              <listitem><para>
                <type>bigint</type>







              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_cmdtype</structfield></term>
              <listitem><para>
                <type>character(1)</type>







              </para>

              <para>
<!--
                Replication action to take. U = Update, I = Insert, D = DELETE
-->
                ץꥱư U =  I =  D = 
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>log_cmddata</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--The data needed to perform the log action-->ư¹ԤΤɬפʥǡ
              </para>

            </listitem>
          </varlistentry>

        </variablelist>










      </para>
    </section>

      <section id="table.sl-node"
               xreflabel="sl_node">
        <title id="table.sl-node-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_node</structname>
        </title>
 

        <para>
<!--
          Holds the list of nodes associated with this namespace.
-->
          ֤̾ϢȤΡɤΥꥹȤ¸ޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_node</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>no_id</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>













              </para>

              <para>
                <!--The unique ID number for the node-->ΡɤФռֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>no_active</structfield></term>
              <listitem><para>
                <type>boolean</type>







              </para>

              <para>
                <!--Is the node active in replication yet?-->ץꥱǥΡɤưƤޤ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>no_comment</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--A human-oriented description of the node-->Ρɤοͼˤ뵭
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>no_spool</structfield></term>
              <listitem><para>
                <type>boolean</type>







              </para>

            </listitem>
          </varlistentry>

        </variablelist>







        <itemizedlist>
          <title>
<!--
            Tables referencing sl_listen via Foreign Key Constraints
-->
            ˤ sl_listen 򻲾Ȥơ֥
          </title>

          <listitem>
            <para>
              <xref linkend="table.sl-listen"/>
            </para>
          </listitem>



          <listitem>
            <para>
              <xref linkend="table.sl-path"/>
            </para>
          </listitem>



          <listitem>
            <para>
              <xref linkend="table.sl-set"/>
            </para>
          </listitem>



          <listitem>
            <para>
              <xref linkend="table.sl-setsync"/>
            </para>
          </listitem>

        </itemizedlist>






      </para>
    </section>

      <section id="table.sl-path"
               xreflabel="sl_path">
         <title id="table.sl-path-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_path</structname>
        </title>
 

        <para>
<!--
          Holds connection information for the paths between nodes, and the synchronisation delay
-->
         Ρɴ֤ηϩФ³Ʊٱ¸ޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_path</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>pa_server</structfield></term>
              <listitem><para>
                <type>integer</type>






                <literal>PRIMARY KEY</literal>












                <literal>REFERENCES</literal> <xref linkend="table.sl-node"/>




              </para>

              <para>
<!--
                The Node ID # (from sl_node.no_id) of the data source
-->
                ǡΡsl_node.no_id Ρ˥Ρɼֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>pa_client</structfield></term>
              <listitem><para>
                <type>integer</type>






                <literal>PRIMARY KEY</literal>












                <literal>REFERENCES</literal> <xref linkend="table.sl-node"/>




              </para>

              <para>
<!--
                The Node ID # (from sl_node.no_id) of the data target
-->
                ǡåȡsl_node.no_id Ρ˥Ρɼֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>pa_conninfo</structfield></term>
              <listitem><para>
                <type>text</type>



                <literal>NOT NULL</literal>





              </para>

              <para>
<!--
                The PostgreSQL connection string used to connect to the source node.
-->
                ǡΡɤ³˻Ѥ PostgreSQL ³ʸ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>pa_connretry</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

              <para>
                <!--The synchronisation delay, in seconds-->ñ̤ˤƱٱ
              </para>

            </listitem>
          </varlistentry>

        </variablelist>







        <itemizedlist>
          <title>
<!--
            Tables referencing sl_listen via Foreign Key Constraints
-->
            ˤ sl_listen 򻲾Ȥơ֥
          </title>

          <listitem>
            <para>
              <xref linkend="table.sl-listen"/>
            </para>
          </listitem>



          <listitem>
            <para>
              <xref linkend="table.sl-subscribe"/>
            </para>
          </listitem>

        </itemizedlist>






      </para>
    </section>

      <section id="view.sl-seqlastvalue"
               xreflabel="sl_seqlastvalue">
        <title id="view.sl-seqlastvalue-title">
         <!--View:-->ӥ塼
         
         <structname>sl_seqlastvalue</structname>
        </title>
 


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_seqlastvalue</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>seq_id</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seq_set</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seq_reloid</structfield></term>
              <listitem><para>
                <type>oid</type>







              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seq_origin</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seq_last_value</structfield></term>
              <listitem><para>
                <type>bigint</type>







              </para>

            </listitem>
          </varlistentry>

        </variablelist>








        <figure>
         <title><!--Definition of view sl_seqlastvalue-->ӥ塼 sl_seqlastvalue </title>
         <programlisting>
SELECT sq.seq_id
, sq.seq_set
, sq.seq_reloid
, s.set_origin AS seq_origin
, sequencelastvalue
(
     (
           (quote_ident
                 (
                       (pgn.nspname)::text
                 ) || &apos;.&apos;::text
           ) || quote_ident
           (
                 (pgc.relname)::text
           )
     )
) AS seq_last_value 
FROM sl_sequence sq
, sl_set s
, pg_class pgc
, pg_namespace pgn 
WHERE (
     (
           (s.set_id = sq.seq_set)
         AND (pgc.oid = sq.seq_reloid)
     )
   AND (pgn.oid = pgc.relnamespace)
);</programlisting>
        </figure>



      </para>
    </section>

      <section id="table.sl-seqlog"
               xreflabel="sl_seqlog">
        <title id="table.sl-seqlog-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_seqlog</structname>
        </title>
 

        <para>
          <!--Log of Sequence updates-->󥹹
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_seqlog</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>seql_seqid</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

              <para>
                <!--Sequence ID-->󥹼̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seql_origin</structfield></term>
              <listitem><para>
                <type>integer</type>







              </para>

              <para>
                <!--Publisher node at which the sequence originates-->󥹤ȯȯԥΡ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seql_ev_seqno</structfield></term>
              <listitem><para>
                <type>bigint</type>







              </para>

              <para>
<!--
                Slony-I Event with which this sequence update is associated
-->
                Υ󥹹ϢȤ Slony-I Event
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seql_last_value</structfield></term>
              <listitem><para>
                <type>bigint</type>







              </para>

              <para>
                <!--Last value published for this sequence-->Υ󥹤ФȯԤ줿ǿ
              </para>

            </listitem>
          </varlistentry>

        </variablelist>





        <variablelist>
          <title><!--Indexes on -->sl_seqlog Υǥå</title>

          <varlistentry>
            <term>sl_seqlog_idx</term>
            <listitem><para>seql_origin, seql_ev_seqno, seql_seqid</para></listitem>
          </varlistentry>

        </variablelist>








      </para>
    </section>

      <section id="table.sl-sequence"
               xreflabel="sl_sequence">
        <title id="table.sl-sequence-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_sequence</structname>
        </title>
 

        <para>
<!--
          Similar to sl_table, each entry identifies a sequence being replicated.
-->
          sl_table Ʊ͡줾Υȥʣ륷󥹤ꤷޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_sequence</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>seq_id</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>













              </para>

              <para>
<!--
                An internally-used ID for Slony-I to use in its sequencing of updates
-->
                Slony-I󥹹˻ѤǻѤ뼱̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seq_reloid</structfield></term>
              <listitem><para>
                <type>oid</type>




                      <literal>UNIQUE</literal>




                <literal>NOT NULL</literal>







              </para>

              <para>
                <!--The OID of the sequence object-->󥹥֥ȤΥ֥ȼ̻ҡOID
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seq_relname</structfield></term>
              <listitem><para>
                <type>name</type>



                <literal>NOT NULL</literal>





              </para>

              <para>
<!--
                The name of the sdequence in pg_catalog.pg_class.relname used to recover from a dump/restore cycle
-->  
               /ꥹȥΤ˻Ѥ pg_catalog.pg_class.relname ˤ륷̾
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seq_nspname</structfield></term>
              <listitem><para>
                <type>name</type>



                <literal>NOT NULL</literal>





              </para>

              <para>
<!--
                The name of the schema in pg_catalog.pg_namespace.nspname used to recover from a dump/restore cycle
-->
               /ꥹȥΤ˻Ѥ pg_catalog.pg_namespace.nspname ˤ륹̾
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seq_set</structfield></term>
              <listitem><para>
                <type>integer</type>












                <literal>REFERENCES</literal> <xref linkend="table.sl-set"/>


              </para>

              <para>
                <!--Indicates which replication set the object is in-->ɤΥץꥱ󥻥åȤ˥֥Ȥ뤫򼨤ޤ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>seq_comment</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--A human-oriented comment-->ͼˤ륳
              </para>

            </listitem>
          </varlistentry>

        </variablelist>










      </para>
    </section>

      <section id="table.sl-set"
               xreflabel="sl_set">
        <title id="table.sl-set-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_set</structname>
        </title>
 

        <para>
          <!--Holds definitions of replication sets.-->ץꥱ󥻥åȤ¸ޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_set</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>set_id</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>













              </para>

              <para>
                <!--A unique ID number for the set.-->åȤФռֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>set_origin</structfield></term>
              <listitem><para>
                <type>integer</type>












                <literal>REFERENCES</literal> <xref linkend="table.sl-node"/>


              </para>

              <para>
                <!--The ID number of the source node for the replication set.-->ץꥱ󥻥åȤФ륽Ρɤμֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>set_locked</structfield></term>
              <listitem><para>
                <type>xxid</type>







              </para>

              <para>
                <!--Indicates whether or not the set is locked.-->åȤåƤ뤫ɤ򼨤ޤ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>set_comment</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--A human-oriented description of the set.-->ͼˤ륻åȤε
              </para>

            </listitem>
          </varlistentry>

        </variablelist>







        <itemizedlist>
          <title>
<!--
            Tables referencing sl_sequence via Foreign Key Constraints
-->
            ˤ sl_sequence 򻲾Ȥơ֥
          </title>

          <listitem>
            <para>
              <xref linkend="table.sl-sequence"/>
            </para>
          </listitem>



          <listitem>
            <para>
              <xref linkend="table.sl-setsync"/>
            </para>
          </listitem>



          <listitem>
            <para>
              <xref linkend="table.sl-subscribe"/>
            </para>
          </listitem>



          <listitem>
            <para>
              <xref linkend="table.sl-table"/>
            </para>
          </listitem>

        </itemizedlist>






      </para>
    </section>

      <section id="table.sl-setsync"
               xreflabel="sl_setsync">
        <title id="table.sl-setsync-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_setsync</structname>
        </title>
 

        <para>
          SYNC <!--information-->
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_setsync</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>ssy_setid</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>


















                <literal>REFERENCES</literal> <xref linkend="table.sl-set"/>


              </para>

              <para>
                <!--ID number of the replication set-->ץꥱ󥻥åȤμֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ssy_origin</structfield></term>
              <listitem><para>
                <type>integer</type>












                <literal>REFERENCES</literal> <xref linkend="table.sl-node"/>


              </para>

              <para>
                <!--ID number of the node-->Ρɤμֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ssy_seqno</structfield></term>
              <listitem><para>
                <type>bigint</type>







              </para>

              <para>
                Slony-I <!--sequence number-->Υֹ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ssy_minxid</structfield></term>
              <listitem><para>
                <type>xxid</type>







              </para>

              <para>
                <!--Earliest XID in provider system affected by SYNC--> SYNC ѤץХƥκǤ XID
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ssy_maxxid</structfield></term>
              <listitem><para>
                <type>xxid</type>







              </para>

              <para>
                <!--Latest XID in provider system affected by SYNC-->SYNC ѤץХƥκǿ XID
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ssy_xip</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Contains the list of XIDs in progress at SYNC time-->SYNC ˤ XID ΥꥹȤ¸Ƥޤ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>ssy_action_list</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
<!--
                action list used during the subscription process. At the time a subscriber copies over data from the origin, it sees all tables in a state somewhere between two SYNC events. Therefore this list must contains all XIDs that are visible at that time, whose operations have therefore already been included in the data copied at the time the initial data copy is done.  Those actions may therefore be filtered out of the first SYNC done after subscribing.
-->
                ɽ˻ѤưꥹȡꥸΡɤΥǡɥΡɤʣ̤2 Ĥ SYNCݴ֤ΤɤǤξ֤ƤΥơ֥˸˹ԤޤäơΥꥹȤϤλǲĻǤƤ XID ޤǤʤФʤ餺Ǥ餽ϡǡʣ̤Ԥ줿ʣ̤줿ǡ˴˴ޤޤƤޤưϽɸ˹Ԥ줿ǽ SYNC ޤ
              </para>

            </listitem>
          </varlistentry>

        </variablelist>










      </para>
    </section>

      <section id="table.sl-subscribe"
               xreflabel="sl_subscribe">
        <title id="table.sl-subscribe-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_subscribe</structname>
        </title>
 

        <para>
          <!--Holds a list of subscriptions on sets-->åȾιɤΥꥹȤ¸Ƥޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_subscribe</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>sub_set</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>


















                <literal>REFERENCES</literal> <xref linkend="table.sl-set"/>


              </para>

              <para>
                <!--ID # (from sl_set) of the set being subscribed to-->ư륻åȤΡsl_set Ρ˼ֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>sub_provider</structfield></term>
              <listitem><para>
                <type>integer</type>












                <literal>REFERENCES</literal> <xref linkend="table.sl-path"/>


              </para>

              <para>
                <!--ID# (from sl_node) of the node providing data-->ǡ򶡵뤹ΡɤΡsl_node Ρ˼ֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>sub_receiver</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>


















                <literal>REFERENCES</literal> <xref linkend="table.sl-path"/>


              </para>

              <para>
                <!--ID# (from sl_node) of the node receiving data from the provider-->ץХǡΡɤΡsl_node Ρ˼ֹ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>sub_forward</structfield></term>
              <listitem><para>
                <type>boolean</type>







              </para>

              <para>
<!--
                Does this provider keep data in sl_log_1/sl_log_2 to allow it to be a provider for other nodes?
-->
               ϤΥץХ¾ΥΡɤФƥץХȤʤ뤳ȤǤ褦˥ǡ sl_log_1/sl_log_2 ¸ΤǤ礦
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>sub_active</structfield></term>
              <listitem><para>
                <type>boolean</type>







              </para>

              <para><!--
                Has this subscription been activated?  This is not set until the subscriber has received COPY data from the provider
-->
               ιɤϵưƤޤ  ϥץХɥΡɤ COPY ǡޤꤵޤ
              </para>

            </listitem>
          </varlistentry>

        </variablelist>










      </para>
    </section>

      <section id="table.sl-table"
               xreflabel="sl_table">
        <title id="table.sl-table-title">
         <!--Table:-->ơ֥롧
         
         <structname>sl_table</structname>
        </title>
 

        <para>
          <!--Holds information about the tables being replicated.-->ʣơ֥˴ؤݻޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_table</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>tab_id</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>













              </para>

              <para>
                <!--Unique key for Slony-I to use to identify the table-->ơ֥ꤹΤ Slony-I Ѥդʥ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>tab_reloid</structfield></term>
              <listitem><para>
                <type>oid</type>




                      <literal>UNIQUE</literal>




                <literal>NOT NULL</literal>







              </para>

              <para>
                <!--The OID of the table in -->pg_catalog.pg_class.oid ˤơ֥Υ֥ȼ̻ҡOID
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>tab_relname</structfield></term>
              <listitem><para>
                <type>name</type>



                <literal>NOT NULL</literal>





              </para>

              <para>
<!--
                The name of the table in pg_catalog.pg_class.relname used to recover from a dump/restore cycle
-->
               /ꥹȥΤ˻Ѥ pg_catalog.pg_class.relname ˤơ֥̾
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>tab_nspname</structfield></term>
              <listitem><para>
                <type>name</type>



                <literal>NOT NULL</literal>





              </para>

              <para>
<!--
                The name of the schema in pg_catalog.pg_namespace.nspname used to recover from a dump/restore cycle
-->
               /ꥹȥΤ˻Ѥ pg_catalog.pg_namespace.nspname ˤ륹̾
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>tab_set</structfield></term>
              <listitem><para>
                <type>integer</type>












                <literal>REFERENCES</literal> <xref linkend="table.sl-set"/>


              </para>

              <para>
                <!--ID of the replication set the table is in-->ơ֥뤬äƤʣåȤμ̻
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>tab_idxname</structfield></term>
              <listitem><para>
                <type>name</type>



                <literal>NOT NULL</literal>





              </para>

              <para>
                <!--The name of the primary index of the table-->ơ֥μ祤ǥå̾
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>tab_altered</structfield></term>
              <listitem><para>
                <type>boolean</type>



                <literal>NOT NULL</literal>





              </para>

              <para>
                <!--Has the table been modified for replication?-->ʣΤơ֥뤬ѹޤ
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>tab_comment</structfield></term>
              <listitem><para>
                <type>text</type>







              </para>

              <para>
                <!--Human-oriented description of the table-->ͼˤơ֥ε
              </para>

            </listitem>
          </varlistentry>

        </variablelist>







        <itemizedlist>
          <title>
            <!--Tables referencing sl_trigger via Foreign Key Constraints--> sl_trigger 򻲾Ȥơ֥
          </title>

          <listitem>
            <para>
              <xref linkend="table.sl-trigger"/>
            </para>
          </listitem>

        </itemizedlist>






      </para>
    </section>

      <section id="table.sl-trigger"
               xreflabel="sl_trigger">
        <title id="table.sl-trigger-title">
         <!--Table:-->ơ֥
         
         <structname>sl_trigger</structname>
        </title>
 

        <para>
          <!--Holds information about triggers on tables managed using Slony-I-->Slony-I Ѥƴơ֥Υȥꥬ˴ؤݻޤ
        </para>


        <para>
          <variablelist>
            <title>
              <!--Structure of --><structname>sl_trigger</structname> ι¤
            </title>


            <varlistentry>
              <term><structfield>trig_tabid</structfield></term>
              <listitem><para>
                <type>integer</type>


                <literal>PRIMARY KEY</literal>


















                <literal>REFERENCES</literal> <xref linkend="table.sl-table"/>


              </para>

              <para>
                <!--Slony-I ID number of table the trigger is on-->ȥꥬäƤơ֥ Slony-I ֹ̻ 
              </para>

            </listitem>
          </varlistentry>

            <varlistentry>
              <term><structfield>trig_tgname</structfield></term>
              <listitem><para>
                <type>name</type>


                <literal>PRIMARY KEY</literal>













              </para>

              <para>
                <!--Indicates the name of a trigger-->ȥꥬ̾򼨤ޤ
              </para>

            </listitem>
          </varlistentry>

        </variablelist>










      </para>
    </section>



<!-- Function add_missing_table_field( text, text, text, text ) -->
    <section id="function.add-missing-table-field-text-text-text-text"
             xreflabel="schemadocadd_missing_table_field( text, text, text, text )">
      <title id="function.add-missing-table-field-text-text-text-text-title">
       add_missing_table_field( text, text, text, text )
      </title>
      <titleabbrev id="function.add-missing-table-field-text-text-text-text-titleabbrev">
       add_missing_table_field( text, text, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>boolean</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Add a column of a given type to a table if it is missing-->⤷¸ߤʤͿ줿ɲäޤ
        <programlisting>
DECLARE
  p_namespace alias for $1;
  p_table     alias for $2;
  p_field     alias for $3;
  p_type      alias for $4;
  v_row       record;
  v_query     text;
BEGIN
  select 1 into v_row from pg_namespace n, pg_class c, pg_attribute a
     where slon_quote_brute(n.nspname) = p_namespace and 
         c.relnamespace = n.oid and
         slon_quote_brute(c.relname) = p_table and
         a.attrelid = c.oid and
         slon_quote_brute(a.attname) = p_field;
  if not found then
    raise notice &#39;Upgrade table %.% - add field %&#39;, p_namespace, p_table, p_field;
    v_query := &#39;alter table &#39; || p_namespace || &#39;.&#39; || p_table || &#39; add column &#39;;
    v_query := v_query || p_field || &#39; &#39; || p_type || &#39;;&#39;;
    execute v_query;
    return &#39;t&#39;;
  else
    return &#39;f&#39;;
  end if;
END;</programlisting>
      </para>
    </section>

<!-- Function altertableforreplication( integer ) -->
    <section id="function.altertableforreplication-integer"
             xreflabel="schemadocaltertableforreplication( integer )">
      <title id="function.altertableforreplication-integer-title">
       altertableforreplication( integer )
      </title>
      <titleabbrev id="function.altertableforreplication-integer-titleabbrev">
       altertableforreplication( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       alterTableForReplication(tab_id)

<!--Sets up a table for replication.
On the origin, this involves adding the &quot;logTrigger()&quot; trigger to the
table.-->
ʣΤơ֥ꤷޤϥꥸΡɾǡơ֥Υȥꥬ &quot;logTrigger()&quot; ɲäΤ˷ޤ

<!--On a subscriber node, this involves disabling triggers and rules, and
adding in the trigger that denies write access to replicated tables.-->
ɥΡɾǡϥȥꥬȥ롼̵ˤʣ줿ơ֥Ф񤭹ߥݤȥꥬɲäޤ

        <programlisting>
declare
	p_tab_id			alias for $1;
	v_no_id				int4;
	v_tab_row			record;
	v_tab_fqname			text;
	v_tab_attkind			text;
	v_n				int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Get our local node ID-->ΥΡɼ̻Ҥμ
	-- ----
	v_no_id := getLocalNodeId(&#39;_schemadoc&#39;);

	-- ----
	-- <!--Get the sl_table row and the current origin of the table.-->sl_table Ԥȥơ֥θߤΥꥸΡɤμ 
	-- <!--Verify that the table currently is NOT in altered state.-->ơ֥뤬ѹ줿֤Ǥʤθ
	-- ----
	select T.tab_reloid, T.tab_set, T.tab_idxname, T.tab_altered,
			S.set_origin, PGX.indexrelid,
			slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
			slon_quote_brute(PGC.relname) as tab_fqname
			into v_tab_row
			from sl_table T, sl_set S,
				&quot;pg_catalog&quot;.pg_class PGC, &quot;pg_catalog&quot;.pg_namespace PGN,
				&quot;pg_catalog&quot;.pg_index PGX, &quot;pg_catalog&quot;.pg_class PGXC
			where T.tab_id = p_tab_id
				and T.tab_set = S.set_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid
				and PGX.indrelid = T.tab_reloid
				and PGX.indexrelid = PGXC.oid
				and PGXC.relname = T.tab_idxname
				for update;
	if not found then
		raise exception &#39;Slony-I: Table with id % not found&#39;, p_tab_id;
	end if;
	v_tab_fqname = v_tab_row.tab_fqname;
	if v_tab_row.tab_altered then
		raise exception &#39;Slony-I: Table % is already in altered state&#39;,
				v_tab_fqname;
	end if;

	v_tab_attkind := determineAttKindUnique(v_tab_row.tab_fqname, 
						v_tab_row.tab_idxname);

	execute &#39;lock table &#39; || v_tab_fqname || &#39; in access exclusive mode&#39;;

	-- ----
	-- <!--Procedures are different on origin and subscriber-->ꥸΡɤȹɥΡɤǤϼ礬ۤʤ
	-- ----
	if v_no_id = v_tab_row.set_origin then
		-- ----
		-- <!--On the Origin we add the log trigger to the table and done-->ꥸΡɾǥơ֥˥ȥꥬɲäλ
		-- ----
		execute &#39;create trigger &quot;_schemadoc_logtrigger_&#39; || 
				p_tab_id || &#39;&quot; after insert or update or delete on &#39; ||
				v_tab_fqname || &#39; for each row execute procedure
				logTrigger (&#39;&#39;_schemadoc&#39;&#39;, &#39;&#39;&#39; || 
					p_tab_id || &#39;&#39;&#39;, &#39;&#39;&#39; || 
					v_tab_attkind || &#39;&#39;&#39;);&#39;;
	else
		-- ----
		-- <!--On the subscriber the thing is a bit more difficult. We want-->ɥΡɾʪϤäȤˤʤޤ
		-- <!--to disable all user- and foreign key triggers and rules.-->ƤΥ桼Фȥꥬȥ롼̵ˤޤ
		-- ----


		-- ----
		-- <!--Disable all existing triggers-->Ƥδ¸Υȥꥬ̵ˤޤ
		-- ----
		update &quot;pg_catalog&quot;.pg_trigger
				set tgrelid = v_tab_row.indexrelid
				where tgrelid = v_tab_row.tab_reloid
				and not exists (
						select true from sl_table TAB,
								sl_trigger TRIG
								where TAB.tab_reloid = tgrelid
								and TAB.tab_id = TRIG.trig_tabid
								and TRIG.trig_tgname = tgname
					);
		get diagnostics v_n = row_count;
		if v_n &gt; 0 then
			update &quot;pg_catalog&quot;.pg_class
					set reltriggers = reltriggers - v_n
					where oid = v_tab_row.tab_reloid;
		end if;

		-- ----
		-- <!--Disable all existing rules-->Ƥδ¸Υ롼̵ˤޤ
		-- ----
		update &quot;pg_catalog&quot;.pg_rewrite
				set ev_class = v_tab_row.indexrelid
				where ev_class = v_tab_row.tab_reloid;
		get diagnostics v_n = row_count;
		if v_n &gt; 0 then
			update &quot;pg_catalog&quot;.pg_class
					set relhasrules = false
					where oid = v_tab_row.tab_reloid;
		end if;

		-- ----
		-- <!--Add the trigger that denies write access to replicated tables-->ʣ줿ơ֥ؤν񤭹ߥݤȥꥬɲäޤ
		-- ----
		execute &#39;create trigger &quot;_schemadoc_denyaccess_&#39; || 
				p_tab_id || &#39;&quot; before insert or update or delete on &#39; ||
				v_tab_fqname || &#39; for each row execute procedure
				denyAccess (&#39;&#39;_schemadoc&#39;&#39;);&#39;;
	end if;

	-- ----
	-- <!--Mark the table altered in our configuration-->ιѹ줿ơ֥˰դޤ
	-- ----
	update sl_table
			set tab_altered = true where tab_id = p_tab_id;

	return p_tab_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function altertablerestore( integer ) -->
    <section id="function.altertablerestore-integer"
             xreflabel="schemadocaltertablerestore( integer )">
      <title id="function.altertablerestore-integer-title">
       altertablerestore( integer )
      </title>
      <titleabbrev id="function.altertablerestore-integer-titleabbrev">
       altertablerestore( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       alterTableRestore (tab_id)

<!--Restores table tab_id from being replicated.-->
ʣ뤳Ȥơ֥ tab_id ꥹȥޤ

<!--On the origin, this simply involves dropping the &quot;logtrigger&quot; trigger.-->
ꥸΡɾǤñ &quot;logtrigger&quot; ȥꥬǤ

<!--On subscriber nodes, this involves dropping the &quot;denyaccess&quot; trigger,
and restoring user triggers and rules.-->
ɥΡɾǤ &quot;denyaccess&quot; ȥꥬ桼ȥꥬȥ롼ꥹȥޤ

        <programlisting>
declare
	p_tab_id			alias for $1;
	v_no_id				int4;
	v_tab_row			record;
	v_tab_fqname			text;
	v_n				int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Get our local node ID-->ΥΡɼ̻Ҥμ
	-- ----
	v_no_id := getLocalNodeId(&#39;_schemadoc&#39;);

	-- ----
	-- <!--Get the sl_table row and the current tables origin. Check-->sl_table ԤȸߤΥơ֥륪ꥸΡɤμ
	-- <!--that the table currently IS in altered state.-->ơ֥ϸѹ֤ˤ뤳Ȥθ
	-- ----
	select T.tab_reloid, T.tab_set, T.tab_altered,
			S.set_origin, PGX.indexrelid,
			slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
			slon_quote_brute(PGC.relname) as tab_fqname
			into v_tab_row
			from sl_table T, sl_set S,
				&quot;pg_catalog&quot;.pg_class PGC, &quot;pg_catalog&quot;.pg_namespace PGN,
				&quot;pg_catalog&quot;.pg_index PGX, &quot;pg_catalog&quot;.pg_class PGXC
			where T.tab_id = p_tab_id
				and T.tab_set = S.set_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid
				and PGX.indrelid = T.tab_reloid
				and PGX.indexrelid = PGXC.oid
				and PGXC.relname = T.tab_idxname
				for update;
	if not found then
		raise exception &#39;Slony-I: Table with id % not found&#39;, p_tab_id;
	end if;
	v_tab_fqname = v_tab_row.tab_fqname;
	if not v_tab_row.tab_altered then
		raise exception &#39;Slony-I: Table % is not in altered state&#39;,
				v_tab_fqname;
	end if;

	execute &#39;lock table &#39; || v_tab_fqname || &#39; in access exclusive mode&#39;;

	-- ----
	-- <!--Procedures are different on origin and subscriber-->ꥸΡɤȹɥΡɤǤϼ礬ۤʤ
	-- ----
	if v_no_id = v_tab_row.set_origin then
		-- ----
		-- <!--On the Origin we just drop the trigger we originally added-->ꥸΡɤǤϸɲäȥꥬñ˺ޤ
		-- ----
		execute &#39;drop trigger &quot;_schemadoc_logtrigger_&#39; || 
				p_tab_id || &#39;&quot; on &#39; || v_tab_fqname;
	else
		-- ----
		-- <!--On the subscriber drop the denyAccess trigger-->ɥΡɤǤ denyAccess ȥꥬκ
		-- ----
		execute &#39;drop trigger &quot;_schemadoc_denyaccess_&#39; || 
				p_tab_id || &#39;&quot; on &#39; || v_tab_fqname;
				
		-- ----
		-- <!--Restore all original triggers-->ƤΥȥꥬΥꥹȥ
		-- ----
		update &quot;pg_catalog&quot;.pg_trigger
				set tgrelid = v_tab_row.tab_reloid
				where tgrelid = v_tab_row.indexrelid;
		get diagnostics v_n = row_count;
		if v_n &gt; 0 then
			update &quot;pg_catalog&quot;.pg_class
					set reltriggers = reltriggers + v_n
					where oid = v_tab_row.tab_reloid;
		end if;

		-- ----
		-- <!--Restore all original rewrite rules-->Ƥθν񤭴롼Υꥹȥ
		-- ----
		update &quot;pg_catalog&quot;.pg_rewrite
				set ev_class = v_tab_row.tab_reloid
				where ev_class = v_tab_row.indexrelid;
		get diagnostics v_n = row_count;
		if v_n &gt; 0 then
			update &quot;pg_catalog&quot;.pg_class
					set relhasrules = true
					where oid = v_tab_row.tab_reloid;
		end if;

	end if;

	-- ----
	-- <!--Mark the table not altered in our configuration-->ιѹʤäơ֥˰դ
	-- ----
	update sl_table
			set tab_altered = false where tab_id = p_tab_id;

	return p_tab_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function cleanupevent(  ) -->
    <section id="function.cleanupevent"
             xreflabel="schemadoccleanupevent(  )">
      <title id="function.cleanupevent-title">
       cleanupevent(  )
      </title>
      <titleabbrev id="function.cleanupevent-titleabbrev">
       cleanupevent(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title> 
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle> 
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--cleaning old data out of sl_confirm, sl_event.  Removes all but the
last sl_confirm row per (origin,receiver), and then removes all events
that are confirmed by all nodes in the whole cluster up to the last
SYNC.-->
         sl_confirm sl_event ŤǡݽʥꥸΡɡ쥷ХΡɡκǿ sl_confirm Ԥ̤ȤƤǸ SYNC ޤǤƤΥ饹̤ƤΥΡɤˤǧ줿Ƥλݤޤ

        <programlisting>
declare
	v_max_row	record;
	v_min_row	record;
	v_max_sync	int8;
begin
	-- ----
	-- <!--First remove all but the oldest confirm row per origin,receiver pair-->ǽˡꥸΡɤȥ쥷ХΡɤȤ߹礻κǤŤǧ줿ΤƤ
	-- ----
	delete from sl_confirm
				where con_origin not in (select no_id from sl_node);
	delete from sl_confirm
				where con_received not in (select no_id from sl_node);
	-- ----
	-- <!--Next remove all but the oldest confirm row per origin,receiver pair.-->˥ꥸΡɤȥ쥷ХΡɤȤ߹礻κǤŤǧ줿ΤƤ
<!--
	&#055;&#055; Ignore confirmations that are younger than 10 minutes. We currently 
	&#055;&#055; have an not confirmed suspicion that a possibly lost transaction due
	&#055;&#055; to a server crash might have been visible to another session, and
	&#055;&#055; that this led to log data that is needed again got removed.
-->
        -- 10 ʬˤäǧ̵롣䤿ϡФΥå夬
        -- ¾Υå󤫤ĻǤˤ롢⤷Ƽ줿
        -- ȥ󥶥ؤθ߳ǧƤʤƤޤ
	-- ----
	for v_max_row in select con_origin, con_received, max(con_seqno) as con_seqno
				from sl_confirm
				where con_timestamp &lt; (CURRENT_TIMESTAMP - &#39;10 min&#39;::interval)
				group by con_origin, con_received
	loop
		delete from sl_confirm
				where con_origin = v_max_row.con_origin
				and con_received = v_max_row.con_received
				and con_seqno &lt; v_max_row.con_seqno;
	end loop;

	-- ----
	-- <!--Then remove all events that are confirmed by all nodes in the-->Ǹ SYNC ޤǤƤΥ饹̤
	-- <!--whole cluster up to the last SYNC-->ƤΥΡɤˤǧ줿Ƥλݤ
	-- ----
	for v_min_row in select con_origin, min(con_seqno) as con_seqno
				from sl_confirm
				group by con_origin
	loop
		select coalesce(max(ev_seqno), 0) into v_max_sync
				from sl_event
				where ev_origin = v_min_row.con_origin
				and ev_seqno &lt;= v_min_row.con_seqno
				and ev_type = &#39;SYNC&#39;;
		if v_max_sync &gt; 0 then
			delete from sl_event
					where ev_origin = v_min_row.con_origin
					and ev_seqno &lt; v_max_sync;
		end if;
	end loop;

	return 0;
end;
</programlisting>
      </para>
    </section>

<!-- Function cleanuplistener(  ) -->
    <section id="function.cleanuplistener"
             xreflabel="schemadoccleanuplistener(  )">
      <title id="function.cleanuplistener-title">
       cleanuplistener(  )
      </title>
      <titleabbrev id="function.cleanuplistener-titleabbrev">
       cleanuplistener(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--look for stale pg_listener entries and submit Async_Unlisten() to them-->
       Ťʤä pg_listener ȥõФ Async_Unlisten() ȯԤޤ
        <programlisting>_Slony_I_cleanupListener</programlisting>
      </para>
    </section>

<!-- Function createevent( name, text ) -->
    <section id="function.createevent-name-text"
             xreflabel="schemadoccreateevent( name, text )">
      <title id="function.createevent-name-text-title">
       createevent( name, text )
      </title>
      <titleabbrev id="function.createevent-name-text-titleabbrev">
       createevent( name, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])

<!--Create an sl_event entry-->sl_event ȥκ
        <programlisting>_Slony_I_createEvent</programlisting>
      </para>
    </section>

<!-- Function createevent( name, text, text ) -->
    <section id="function.createevent-name-text-text"
             xreflabel="schemadoccreateevent( name, text, text )">
      <title id="function.createevent-name-text-text-title">
       createevent( name, text, text )
      </title>
      <titleabbrev id="function.createevent-name-text-text-titleabbrev">
       createevent( name, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])

<!--Create an sl_event entry-->sl_event ȥκ
        <programlisting>_Slony_I_createEvent</programlisting>
      </para>
    </section>

<!-- Function createevent( name, text, text, text ) -->
    <section id="function.createevent-name-text-text-text"
             xreflabel="schemadoccreateevent( name, text, text, text )">
      <title id="function.createevent-name-text-text-text-title">
       createevent( name, text, text, text )
      </title>
      <titleabbrev id="function.createevent-name-text-text-text-titleabbrev">
       createevent( name, text, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])

<!--Create an sl_event entry-->sl_event ȥκ
        <programlisting>_Slony_I_createEvent</programlisting>
      </para>
    </section>

<!-- Function createevent( name, text, text, text, text ) -->
    <section id="function.createevent-name-text-text-text-text"
             xreflabel="schemadoccreateevent( name, text, text, text, text )">
      <title id="function.createevent-name-text-text-text-text-title">
       createevent( name, text, text, text, text )
      </title>
      <titleabbrev id="function.createevent-name-text-text-text-text-titleabbrev">
       createevent( name, text, text, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])

<!--Create an sl_event entry-->sl_event ȥκ
        <programlisting>_Slony_I_createEvent</programlisting>
      </para>
    </section>

<!-- Function createevent( name, text, text, text, text, text ) -->
    <section id="function.createevent-name-text-text-text-text-text"
             xreflabel="schemadoccreateevent( name, text, text, text, text, text )">
      <title id="function.createevent-name-text-text-text-text-text-title">
       createevent( name, text, text, text, text, text )
      </title>
      <titleabbrev id="function.createevent-name-text-text-text-text-text-titleabbrev">
       createevent( name, text, text, text, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])

<!--Create an sl_event entry--> sl_event ȥκ
        <programlisting>_Slony_I_createEvent</programlisting>
      </para>
    </section>

<!-- Function createevent( name, text, text, text, text, text, text ) -->
    <section id="function.createevent-name-text-text-text-text-text-text"
             xreflabel="schemadoccreateevent( name, text, text, text, text, text, text )">
      <title id="function.createevent-name-text-text-text-text-text-text-title">
       createevent( name, text, text, text, text, text, text )
      </title>
      <titleabbrev id="function.createevent-name-text-text-text-text-text-text-titleabbrev">
       createevent( name, text, text, text, text, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])

<!--Create an sl_event entry-->sl_event ȥκ
        <programlisting>_Slony_I_createEvent</programlisting>
      </para>
    </section>

<!-- Function createevent( name, text, text, text, text, text, text, text ) -->
    <section id="function.createevent-name-text-text-text-text-text-text-text"
             xreflabel="schemadoccreateevent( name, text, text, text, text, text, text, text )">
      <title id="function.createevent-name-text-text-text-text-text-text-text-title">
       createevent( name, text, text, text, text, text, text, text )
      </title>
      <titleabbrev id="function.createevent-name-text-text-text-text-text-text-text-titleabbrev">
       createevent( name, text, text, text, text, text, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])

<!--Create an sl_event entry-->sl_event ȥκ
        <programlisting>_Slony_I_createEvent</programlisting>
      </para>
    </section>

<!-- Function createevent( name, text, text, text, text, text, text, text, text ) -->
    <section id="function.createevent-name-text-text-text-text-text-text-text-text"
             xreflabel="schemadoccreateevent( name, text, text, text, text, text, text, text, text )">
      <title id="function.createevent-name-text-text-text-text-text-text-text-text-title">
       createevent( name, text, text, text, text, text, text, text, text )
      </title>
      <titleabbrev id="function.createevent-name-text-text-text-text-text-text-text-text-titleabbrev">
       createevent( name, text, text, text, text, text, text, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])

<!--Create an sl_event entry-->sl_event ȥκ
        <programlisting>_Slony_I_createEvent</programlisting>
      </para>
    </section>

<!-- Function createevent( name, text, text, text, text, text, text, text, text, text ) -->
    <section id="function.createevent-name-text-text-text-text-text-text-text-text-text"
             xreflabel="schemadoccreateevent( name, text, text, text, text, text, text, text, text, text )">
      <title id="function.createevent-name-text-text-text-text-text-text-text-text-text-title">
       createevent( name, text, text, text, text, text, text, text, text, text )
      </title>
      <titleabbrev id="function.createevent-name-text-text-text-text-text-text-text-text-text-titleabbrev">
       createevent( name, text, text, text, text, text, text, text, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]])

<!--Create an sl_event entry-->sl_event ȥκ
        <programlisting>_Slony_I_createEvent</programlisting>
      </para>
    </section>

<!-- Function ddlscript( integer, text, integer ) -->
    <section id="function.ddlscript-integer-text-integer"
             xreflabel="schemadocddlscript( integer, text, integer )">
      <title id="function.ddlscript-integer-text-integer-title">
       ddlscript( integer, text, integer )
      </title>
      <titleabbrev id="function.ddlscript-integer-text-integer-titleabbrev">
       ddlscript( integer, text, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       ddlScript(set_id, script, only_on_node)

<!--Generates a SYNC event, runs the script on the origin, and then
generates a DDL_SCRIPT event to request it to be run on replicated
slaves.-->
SYNC ݤꥸΡɤǥץȤ¹Ԥʣ줿졼־Ǥ줬¹Ԥ褦׵᤹ DDL_SCRIPT ݤޤ

        <programlisting>
declare
	p_set_id			alias for $1;
	p_script			alias for $2;
	p_only_on_node		alias for $3;
	v_set_origin		int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that the set exists and originates here-->åȤ¸ߤȯθ
	-- ----
	select set_origin into v_set_origin
			from sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_set_id;
	end if;
	if v_set_origin &lt;&gt; getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				p_set_id;
	end if;

	-- ----
	-- <!--Create a SYNC event, run the script and generate the DDL_SCRIPT event-->SYNC ݤκץȤ¹Ԥ DDL_SCRIPT ݤ
	-- ----
	perform createEvent(&#39;_schemadoc&#39;, &#39;SYNC&#39;, NULL);
	perform ddlScript_int(p_set_id, p_script, p_only_on_node);
	perform updateRelname(p_set_id, p_only_on_node);
	return  createEvent(&#39;_schemadoc&#39;, &#39;DDL_SCRIPT&#39;, 
			p_set_id, p_script, p_only_on_node);
end;
</programlisting>
      </para>
    </section>

<!-- Function ddlscript_int( integer, text, integer ) -->
    <section id="function.ddlscript-int-integer-text-integer"
             xreflabel="schemadocddlscript_int( integer, text, integer )">
      <title id="function.ddlscript-int-integer-text-integer-title">
       ddlscript_int( integer, text, integer )
      </title>
      <titleabbrev id="function.ddlscript-int-integer-text-integer-titleabbrev">
       ddlscript_int( integer, text, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       ddlScript_int(set_id, script, only_on_node)

<!--Processes the DDL_SCRIPT event.  On slave nodes, this restores
original triggers/rules, runs the script, and then puts tables back
into replicated mode.
-->
DDL_SCRIPT ݤμ¹ԡ졼֥ΡɤǸΥȥꥬ/롼ꥹȥץȤ¹ԡƥơ֥ʣ줿֤ᤷޤ

        <programlisting>
declare
	p_set_id			alias for $1;
	p_script			alias for $2;
	p_only_on_node		alias for $3;
	v_set_origin		int4;
	v_no_id				int4;
	v_row				record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that we either are the set origin or a current-->䤿ϥåȥꥸΡɤ⤷
	-- <!--subscriber of the set.-->åȤθߤιɥΡɤθ
	-- ----
	v_no_id := getLocalNodeId(&#39;_schemadoc&#39;);
	select set_origin into v_set_origin
			from sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_set_id;
	end if;
	if v_set_origin &lt;&gt; v_no_id
			and not exists (select 1 from sl_subscribe
						where sub_set = p_set_id
						and sub_receiver = v_no_id)
	then
		return 0;
	end if;

	-- ----
	-- <!--If execution on only one node is requested, check that-->⤷ä 1 ĤΥΡɤǼ¹Ԥ׵ᤵ
	-- <!--we are that node.-->䤿ϤΥΡɤɤ򸡺
	-- ----
	if p_only_on_node &gt; 0 and p_only_on_node &lt;&gt; v_no_id then
		return 0;
	end if;

	-- ----
	-- <!--Restore all original triggers and rules-->ƤθΥȥꥬȥ롼ꥹȥ
	-- ----
	for v_row in select * from sl_table
			where tab_set = p_set_id
	loop
		perform alterTableRestore(v_row.tab_id);
	end loop;

	-- ----
	-- <!--Run the script-->ץȤμ¹
	-- ----
	execute p_script;

	-- ----
	-- <!--Put all tables back into replicated mode-->ƤΥơ֥ʣ줿֤᤹
	-- ----
	for v_row in select * from sl_table
			where tab_set = p_set_id
	loop
		perform alterTableForReplication(v_row.tab_id);
	end loop;

	return p_set_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function denyaccess(  ) -->
    <section id="function.denyaccess"
             xreflabel="schemadocdenyaccess(  )">
      <title id="function.denyaccess-title">
       denyaccess(  )
      </title>
      <titleabbrev id="function.denyaccess-titleabbrev">
       denyaccess(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>&quot;trigger&quot;</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Trigger function to prevent modifications to a table on a subscriber-->
       ɥΡɾΥơ֥ѹɤȥꥬؿ
        <programlisting>_Slony_I_denyAccess</programlisting>
      </para>
    </section>

<!-- Function determineattkindserial( text ) -->
    <section id="function.determineattkindserial-text"
             xreflabel="schemadocdetermineattkindserial( text )">
      <title id="function.determineattkindserial-text-title">
       determineattkindserial( text )
      </title>
      <titleabbrev id="function.determineattkindserial-text-titleabbrev">
       determineattkindserial( text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
       determineAttKindSerial (tab_fqname)

<!--A table was that was specified without a primary key is added to the
replication. Assume that tableAddKey() was called before and finish
the creation of the serial column. The return an attkind according to
that.-->
ץꥱ˼祭ʤꤵ줿ơ֥ɲát tableAddKey() ƤФ졢ꥢκλꤷޤ˴Ť attkind ᤷޤ

        <programlisting>
declare
	p_tab_fqname            alias for $1;
	v_tab_fqname_quoted	text default &#39;&#39;;
	v_attkind		text default &#39;&#39;;
	v_attrow		record;
	v_have_serial		bool default &#39;f&#39;;
begin
	v_tab_fqname_quoted := slon_quote_input(p_tab_fqname);
	--
	-- <!--if we find the Slony-I special serial column.-->⤷ Slony-I ̤ʥꥢȯС
	-- <!--Loop over the attributes of this relation-->Υ졼°ǥ롼פ
	-- <!--and add a &quot;v&quot; for every user column, and a &quot;k&quot;-->ƤΥ桼 &quot;v&quot;  &quot;k&quot; ɲäޤ

	--
	for v_attrow in select PGA.attnum, PGA.attname
			from &quot;pg_catalog&quot;.pg_class PGC,
			    &quot;pg_catalog&quot;.pg_namespace PGN,
				&quot;pg_catalog&quot;.pg_attribute PGA
			where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
			    slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGN.oid = PGC.relnamespace
				and PGA.attrelid = PGC.oid
				and not PGA.attisdropped
				and PGA.attnum &gt; 0
			order by attnum
	loop
		if v_attrow.attname = &#39;_Slony-I_schemadoc_rowID&#39; then
		    v_attkind := v_attkind || &#39;k&#39;;
			v_have_serial := &#39;t&#39;;
		else
			v_attkind := v_attkind || &#39;v&#39;;
		end if;
	end loop;
	
	--
	-- <!--A table must have at least one attribute, so not finding-->ơ֥ˤϾʤȤ 1 Ĥ°ɬפǡ
	-- <!--anything means the table does not exist.-->°Ĥʤ礽Υơ֥¸ߤʤȤˤʤޤ
	--
	if not found then
		raise exception &#39;Slony-I: table % not found&#39;, v_tab_fqname_quoted;
	end if;

	--
	-- If it does not have the special serial column, we
	-- should not have been called in the first place.
	--
	if not v_have_serial then
		raise exception &#39;Slony-I: table % does not have the serial key&#39;,
				v_tab_fqname_quoted;
	end if;

	execute &#39;update &#39; || v_tab_fqname_quoted ||
		&#39; set &quot;_Slony-I_schemadoc_rowID&quot; =&#39; ||
		&#39; &quot;pg_catalog&quot;.nextval(&#39;&#39;sl_rowid_seq&#39;&#39;);&#39;;
	execute &#39;alter table only &#39; || v_tab_fqname_quoted ||
		&#39; add unique (&quot;_Slony-I_schemadoc_rowID&quot;);&#39;;
	execute &#39;alter table only &#39; || v_tab_fqname_quoted ||
		&#39; alter column &quot;_Slony-I_schemadoc_rowID&quot; &#39; ||
		&#39; set not null;&#39;;

	--
	-- <!--Return the resulting Slony-I attkind-->̤ Slony-I attkind ֤ޤ
	--
	return v_attkind;
end;
</programlisting>
      </para>
    </section>

<!-- Function determineattkindunique( text, name ) -->
    <section id="function.determineattkindunique-text-name"
             xreflabel="schemadocdetermineattkindunique( text, name )">
      <title id="function.determineattkindunique-text-name-title">
       determineattkindunique( text, name )
      </title>
      <titleabbrev id="function.determineattkindunique-text-name-titleabbrev">
       determineattkindunique( text, name )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
       determineAttKindUnique (tab_fqname, indexname)

<!--Given a tablename, return the Slony-I specific attkind (used for the
log trigger) of the table. Use the specified unique index or the
primary key (if indexname is NULL).-->
tablename ꤷʥȥꥬǻѤ Slony-I ͭ attkind ֤ޤꤵ줿դΥǥå⤷ϡindexname   NULLˤǤм祭Ѥޤ

        <programlisting>
declare
	p_tab_fqname    	alias for $1;
	v_tab_fqname_quoted	text default &#39;&#39;;
	p_idx_name		alias for $2;
	v_idx_name_quoted	text;
	v_idxrow		record;
	v_attrow		record;
	v_i			integer;
	v_attno			int2;
	v_attkind		text default &#39;&#39;;
	v_attfound		bool;
begin
	v_tab_fqname_quoted := slon_quote_input(p_tab_fqname);
	v_idx_name_quoted := slon_quote_brute(p_idx_name);
	--
	-- <!--Ensure that the table exists-->ơ֥뤬¸ߤ뤫γξ
	--
	if (select PGC.relname
				from &quot;pg_catalog&quot;.pg_class PGC,
					&quot;pg_catalog&quot;.pg_namespace PGN
				where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
					slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace) is null then
		raise exception &#39;Slony-I: table % not found&#39;, v_tab_fqname_quoted;
	end if;

	--
	-- <!--Lookup the tables primary key or the specified unique index-->ơ֥祭⤷ΰեǥå򻲾Ȥޤ
	--
	if p_idx_name isnull then
		raise exception &#39;Slony-I: index name must be specified&#39;;
	else
		select PGXC.relname, PGX.indexrelid, PGX.indkey
				into v_idxrow
				from &quot;pg_catalog&quot;.pg_class PGC,
					&quot;pg_catalog&quot;.pg_namespace PGN,
					&quot;pg_catalog&quot;.pg_index PGX,
					&quot;pg_catalog&quot;.pg_class PGXC
				where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
					slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace
					and PGX.indrelid = PGC.oid
					and PGX.indexrelid = PGXC.oid
					and PGX.indisunique
					and slon_quote_brute(PGXC.relname) = v_idx_name_quoted;
		if not found then
			raise exception &#39;Slony-I: table % has no unique index %&#39;,
					v_tab_fqname_quoted, v_idx_name_quoted;
		end if;
	end if;

	--
	-- <!--Loop over the tables attributes and check if they are-->ơ֥°롼פƤ餬ǥå°ޤ
	-- <!--index attributes. If so, add a &quot;k&quot; to the return value,-->ǥå°Ǥ֤ͤ &quot;k&quot; դ
	-- <!--otherwise add a &quot;v&quot;.-->ʤ &quot;v&quot; դޤ
	--
	for v_attrow in select PGA.attnum, PGA.attname
			from &quot;pg_catalog&quot;.pg_class PGC,
			    &quot;pg_catalog&quot;.pg_namespace PGN,
				&quot;pg_catalog&quot;.pg_attribute PGA
			where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
			    slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGN.oid = PGC.relnamespace
				and PGA.attrelid = PGC.oid
				and not PGA.attisdropped
				and PGA.attnum &gt; 0
			order by attnum
	loop
		v_attfound = &#39;f&#39;;

		v_i := 0;
		loop
			select indkey[v_i] into v_attno from &quot;pg_catalog&quot;.pg_index
					where indexrelid = v_idxrow.indexrelid;
			if v_attno isnull or v_attno = 0 then
				exit;
			end if;
			if v_attrow.attnum = v_attno then
				v_attfound = &#39;t&#39;;
				exit;
			end if;
			v_i := v_i + 1;
		end loop;

		if v_attfound then
			v_attkind := v_attkind || &#39;k&#39;;
		else
			v_attkind := v_attkind || &#39;v&#39;;
		end if;
	end loop;

	--
	-- <!--Return the resulting attkind-->̤ attkind ֤ޤ
	--
	return v_attkind;
end;
</programlisting>
      </para>
    </section>

<!-- Function determineidxnameserial( text ) -->
    <section id="function.determineidxnameserial-text"
             xreflabel="schemadocdetermineidxnameserial( text )">
      <title id="function.determineidxnameserial-text-title">
       determineidxnameserial( text )
      </title>
      <titleabbrev id="function.determineidxnameserial-text-titleabbrev">
       determineidxnameserial( text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>name</seg>
        </seglistitem>
       </segmentedlist>
 
       determineIdxnameSerial (tab_fqname)

<!--Given a tablename, construct the index name of the serial column.-->
tablename ꤷꥢΥǥå̾ۤޤ

        <programlisting>
declare
	p_tab_fqname	alias for $1;
	v_tab_fqname_quoted	text default &#39;&#39;;
	v_row			record;
begin
	v_tab_fqname_quoted := slon_quote_input(p_tab_fqname);
	--
	-- <!--Lookup the table name alone-->ñȤ˥ơ֥̾򻲾Ȥޤ
	--
	select PGC.relname
			into v_row
			from &quot;pg_catalog&quot;.pg_class PGC,
				&quot;pg_catalog&quot;.pg_namespace PGN
			where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
				slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGN.oid = PGC.relnamespace;
	if not found then
		raise exception &#39;Slony-I: table % not found&#39;,
				v_tab_fqname_quoted;
	end if;

	--
	-- <!--Return the found index name-->Ĥäǥå֤̾ޤ
	--
	return v_row.relname || &#39;__Slony-I_schemadoc_rowID_key&#39;;
end;
</programlisting>
      </para>
    </section>

<!-- Function determineidxnameunique( text, name ) -->
    <section id="function.determineidxnameunique-text-name"
             xreflabel="schemadocdetermineidxnameunique( text, name )">
      <title id="function.determineidxnameunique-text-name-title">
       determineidxnameunique( text, name )
      </title>
      <titleabbrev id="function.determineidxnameunique-text-name-titleabbrev">
       determineidxnameunique( text, name )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>name</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION determineIdxnameUnique (tab_fqname, indexname)

<!--Given a tablename, tab_fqname, check that the unique index, indexname,
exists or return the primary key index name for the table.  If there
is no unique index, it raises an exception.-->
tablename  tab_fqname ꤷΰեǥåǥå̾и򸡺뤫⤷ϥơ֥μ祭ǥå֤̾ޤդΥǥå̵硢㳰ޤ

        <programlisting>
declare
	p_tab_fqname    	alias for $1;
	v_tab_fqname_quoted	text default &#39;&#39;;
	p_idx_name		alias for $2;
	v_idxrow		record;
begin
	v_tab_fqname_quoted := slon_quote_input(p_tab_fqname);
	--
	-- <!--Ensure that the table exists-->ơ֥뤬¸ߤ뤫γξ
	--
	if (select PGC.relname
				from &quot;pg_catalog&quot;.pg_class PGC,
					&quot;pg_catalog&quot;.pg_namespace PGN
				where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
					slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace) is null then
		raise exception &#39;Slony-I: table % not found&#39;, v_tab_fqname_quoted;
	end if;

	--
	-- <!--Lookup the tables primary key or the specified unique index-->ơ֥祭⤷ΰեǥåλ
	--
	if p_idx_name isnull then
		select PGXC.relname
				into v_idxrow
				from &quot;pg_catalog&quot;.pg_class PGC,
					&quot;pg_catalog&quot;.pg_namespace PGN,
					&quot;pg_catalog&quot;.pg_index PGX,
					&quot;pg_catalog&quot;.pg_class PGXC
				where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
					slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace
					and PGX.indrelid = PGC.oid
					and PGX.indexrelid = PGXC.oid
					and PGX.indisprimary;
		if not found then
			raise exception &#39;Slony-I: table % has no primary key&#39;,
					v_tab_fqname_quoted;
		end if;
	else
		select PGXC.relname
				into v_idxrow
				from &quot;pg_catalog&quot;.pg_class PGC,
					&quot;pg_catalog&quot;.pg_namespace PGN,
					&quot;pg_catalog&quot;.pg_index PGX,
					&quot;pg_catalog&quot;.pg_class PGXC
				where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
					slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
					and PGN.oid = PGC.relnamespace
					and PGX.indrelid = PGC.oid
					and PGX.indexrelid = PGXC.oid
					and PGX.indisunique
					and slon_quote_brute(PGXC.relname) = slon_quote_input(p_idx_name);
		if not found then
			raise exception &#39;Slony-I: table % has no unique index %&#39;,
					v_tab_fqname_quoted, p_idx_name;
		end if;
	end if;

	--
	-- <!--Return the found index name-->Ĥäǥå֤̾ޤ
	--
	return v_idxrow.relname;
end;
</programlisting>
      </para>
    </section>

<!-- Function disablenode( integer ) -->
    <section id="function.disablenode-integer"
             xreflabel="schemadocdisablenode( integer )">
      <title id="function.disablenode-integer-title">
       disablenode( integer )
      </title>
      <titleabbrev id="function.disablenode-integer-titleabbrev">
       disablenode( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--process DISABLE_NODE event for node no_id-->
       Ρ no_id Ф DISABLE_NODE ݤν

<!--NOTE: This is not yet implemented!-->Ф񤭡̤Ƥޤ
        <programlisting>
declare
	p_no_id			alias for $1;
begin
	-- **** TODO ****
	raise exception &#39;Slony-I: disableNode() not implemented&#39;;
end;
</programlisting>
      </para>
    </section>

<!-- Function disablenode_int( integer ) -->
    <section id="function.disablenode-int-integer"
             xreflabel="schemadocdisablenode_int( integer )">
      <title id="function.disablenode-int-integer-title">
       disablenode_int( integer )
      </title>
      <titleabbrev id="function.disablenode-int-integer-titleabbrev">
       disablenode_int( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       
        <programlisting>
declare
	p_no_id			alias for $1;
begin
	-- **** TODO ****
	raise exception &#39;Slony-I: disableNode_int() not implemented&#39;;
end;
</programlisting>
      </para>
    </section>

<!-- Function droplisten( integer, integer, integer ) -->
    <section id="function.droplisten-integer-integer-integer"
             xreflabel="schemadocdroplisten( integer, integer, integer )">
      <title id="function.droplisten-integer-integer-integer-title">
       droplisten( integer, integer, integer )
      </title>
      <titleabbrev id="function.droplisten-integer-integer-integer-titleabbrev">
       droplisten( integer, integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       dropListen (li_origin, li_provider, li_receiver)

<!--Generate the DROP_LISTEN event.-->DROP_LISTEN ݤ
        <programlisting>
declare
	p_li_origin	alias for $1;
	p_li_provider	alias for $2;
	p_li_receiver	alias for $3;
begin
	return -1;

	perform dropListen_int(p_li_origin, 
			p_li_provider, p_li_receiver);
	
	return  createEvent (&#39;_schemadoc&#39;, &#39;DROP_LISTEN&#39;,
			p_li_origin, p_li_provider, p_li_receiver);
end;
</programlisting>
      </para>
    </section>

<!-- Function droplisten_int( integer, integer, integer ) -->
    <section id="function.droplisten-int-integer-integer-integer"
             xreflabel="schemadocdroplisten_int( integer, integer, integer )">
      <title id="function.droplisten-int-integer-integer-integer-title">
       droplisten_int( integer, integer, integer )
      </title>
      <titleabbrev id="function.droplisten-int-integer-integer-integer-titleabbrev">
       droplisten_int( integer, integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       dropListen (li_origin, li_provider, li_receiver)

<!--Process the DROP_LISTEN event, deleting the sl_listen entry for
the indicated (origin,provider,receiver) combination.-->
DROP_LISTEN ݤνؼ줿ʥꥸΡɡץХΡɡ쥷ХΡɡȤ߹碌Ф sl_listen ݤκ

        <programlisting>
declare
	p_li_origin		alias for $1;
	p_li_provider	alias for $2;
	p_li_receiver	alias for $3;
begin
	return -1;

	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table sl_config_lock;

	delete from sl_listen
			where li_origin = p_li_origin
			and li_provider = p_li_provider
			and li_receiver = p_li_receiver;
	if found then
		return 1;
	else
		return 0;
	end if;
end;
</programlisting>
      </para>
    </section>

<!-- Function dropnode( integer ) -->
    <section id="function.dropnode-integer"
             xreflabel="schemadocdropnode( integer )">
      <title id="function.dropnode-integer-title">
       dropnode( integer )
      </title>
      <titleabbrev id="function.dropnode-integer-titleabbrev">
       dropnode( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--generate DROP_NODE event to drop node node_id from replication-->ץꥱ󤫤Ρ node_id  DROP_NODE ݤ

        <programlisting>
declare
	p_no_id			alias for $1;
	v_node_row		record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that this got called on a different node-->ۤʤäΡɤǸƤФ줿θ
	-- ----
	if p_no_id = getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: DROP_NODE cannot initiate on the dropped node&#39;;
	end if;

	select * into v_node_row from sl_node
			where no_id = p_no_id
			for update;
	if not found then
		raise exception &#39;Slony-I: unknown node ID %&#39;, p_no_id;
	end if;

	-- ----
	-- <!--Make sure we do not break other nodes subscriptions with this-->ˤ¾ΥΡɵҤƤʤγǧ
	-- ----
	if exists (select true from sl_subscribe
			where sub_provider = p_no_id)
	then
		raise exception &#39;Slony-I: Node % is still configured as data provider&#39;,
				p_no_id;
	end if;

	-- ----
	-- <!--Make sure no set originates there any more-->åȤ⤦ȯʤγǧ
	-- ----
	if exists (select true from sl_set
			where set_origin = p_no_id)
	then
		raise exception &#39;Slony-I: Node % is still origin of one or more sets&#39;,
				p_no_id;
	end if;

	-- ----
	-- <!--Call the internal drop functionality and generate the event-->κǽθƤӽФȻݤ
	-- ----
	perform dropNode_int(p_no_id);
	return  createEvent(&#39;_schemadoc&#39;, &#39;DROP_NODE&#39;,
									p_no_id);
end;
</programlisting>
      </para>
    </section>

<!-- Function dropnode_int( integer ) -->
    <section id="function.dropnode-int-integer"
             xreflabel="schemadocdropnode_int( integer )">
      <title id="function.dropnode-int-integer-title">
       dropnode_int( integer )
      </title>
      <titleabbrev id="function.dropnode-int-integer-titleabbrev">
       dropnode_int( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--internal function to process DROP_NODE event to drop node node_id from replication-->
       ץꥱ󤫤Ρ node_id  DROP_NODE ݤؿ 
        <programlisting>
declare
	p_no_id			alias for $1;
	v_tab_row		record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--If the dropped node is a remote node, clean the configuration-->줿Ρɤ֥ΡɤǤСФ
	-- <!--from all traces for it.-->ƤΥȥ졼鹽ݽ
	-- ----
	if p_no_id &lt;&gt; getLocalNodeId(&#39;_schemadoc&#39;) then
		delete from sl_subscribe
				where sub_receiver = p_no_id;
		delete from sl_listen
				where li_origin = p_no_id
					or li_provider = p_no_id
					or li_receiver = p_no_id;
		delete from sl_path
				where pa_server = p_no_id
					or pa_client = p_no_id;
		delete from sl_confirm
				where con_origin = p_no_id
					or con_received = p_no_id;
		delete from sl_event
				where ev_origin = p_no_id;
		delete from sl_node
				where no_id = p_no_id;

		return p_no_id;
	end if;

	-- ----
	-- <!--This is us ... deactivate the node for now, the daemon-->ϼʬã  Ρɤ򺣸ߤ̵ˤޤ
	-- <!--will call uninstallNode() in a separate transaction.-->ǡ̤Υȥ󥶥 uninstallNode() ƤӽФޤ
	-- ----
	update sl_node
			set no_active = false
			where no_id = p_no_id;

	-- Rewrite sl_listen table
	perform RebuildListenEntries();

	return p_no_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function droppath( integer, integer ) -->
    <section id="function.droppath-integer-integer"
             xreflabel="schemadocdroppath( integer, integer )">
      <title id="function.droppath-integer-integer-title">
       droppath( integer, integer )
      </title>
      <titleabbrev id="function.droppath-integer-integer-titleabbrev">
       droppath( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Generate DROP_PATH event to drop path from pa_server to pa_client-->
       pa_server  pa_client ؤηϩ DROP_PATH ݤޤ
        <programlisting>
declare
	p_pa_server		alias for $1;
	p_pa_client		alias for $2;
	v_row			record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--There should be no existing subscriptions. Auto unsubscribing-->¸ιɤ¸ߤޤ
	-- <!--is considered too dangerous. -->ưɲ˴ȹͤޤ
	-- ----
	for v_row in select sub_set, sub_provider, sub_receiver
			from sl_subscribe
			where sub_provider = p_pa_server
			and sub_receiver = p_pa_client
	loop
		raise exception 
			&#39;Slony-I: Path cannot be dropped, subscription of set % needs it&#39;,
			v_row.sub_set;
	end loop;

	-- ----
	-- <!--Drop all sl_listen entries that depend on this path-->ηϩ˰¸Ƥ sl_listen ȥޤ
	-- ----
	for v_row in select li_origin, li_provider, li_receiver
			from sl_listen
			where li_provider = p_pa_server
			and li_receiver = p_pa_client
	loop
		perform dropListen(
				v_row.li_origin, v_row.li_provider, v_row.li_receiver);
	end loop;

	-- ----
	-- <!--Now drop the path and create the event-->Ƿϩݤޤ
	-- ----
	perform dropPath_int(p_pa_server, p_pa_client);

	-- Rewrite sl_listen table
	perform RebuildListenEntries();

	return  createEvent (&#39;_schemadoc&#39;, &#39;DROP_PATH&#39;,
			p_pa_server, p_pa_client);
end;
</programlisting>
      </para>
    </section>

<!-- Function droppath_int( integer, integer ) -->
    <section id="function.droppath-int-integer-integer"
             xreflabel="schemadocdroppath_int( integer, integer )">
      <title id="function.droppath-int-integer-integer-title">
       droppath_int( integer, integer )
      </title>
      <titleabbrev id="function.droppath-int-integer-integer-titleabbrev">
       droppath_int( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Process DROP_PATH event to drop path from pa_server to pa_client-->
       pa_server  pa_client ؤηϩ DROP_PATH ݤν
        <programlisting>
declare
	p_pa_server		alias for $1;
	p_pa_client		alias for $2;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Remove any dangling sl_listen entries with the server-->Ƥ֤ sl_listen ȥץХȤƤ
	-- <!--as provider and the client as receiver. This must have-->Сӥ쥷ФȤƤΥ饤Ȥ롣
	-- <!--been cleared out before, but obviously was not.-->Ϥä᤯ݽ٤餫ˤʤäƤޤ
	-- ----
	delete from sl_listen
			where li_provider = p_pa_server
			and li_receiver = p_pa_client;

	delete from sl_path
			where pa_server = p_pa_server
			and pa_client = p_pa_client;

	if found then
		-- <!--Rewrite sl_listen table-->sl_listen ơ֥ν񤭴
		perform RebuildListenEntries();

		return 1;
	else
		-- <!--Rewrite sl_listen table-->sl_listen ơ֥ν񤭴
		perform RebuildListenEntries();

		return 0;
	end if;
end;
</programlisting>
      </para>
    </section>

<!-- Function dropset( integer ) -->
    <section id="function.dropset-integer"
             xreflabel="schemadocdropset( integer )">
      <title id="function.dropset-integer-title">
       dropset( integer )
      </title>
      <titleabbrev id="function.dropset-integer-titleabbrev">
       dropset( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Process DROP_SET event to drop replication of set set_id.  This involves:
- Restoring original triggers and rules
- Removing all traces of the set configuration, including sequences, tables, subscribers, syncs, and the set itself-->
       å set_id Υץꥱ DROP_SET ݤνˤϰʲޤࡧ Υȥꥬȥ롼Υꥹȥ 󥹡ơ֥롢ɥΡɡsyncӥåȤΤΤޤॻåȹƤΥȥ졼κ
        <programlisting>
declare
	p_set_id			alias for $1;
	v_origin			int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;
	
	-- ----
	-- <!--Check that the set exists and originates here-->åȤ¸ߤȯ뤳Ȥθ
	-- ----
	select set_origin into v_origin from sl_set
			where set_id = p_set_id;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_set_id;
	end if;
	if v_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				p_set_id;
	end if;

	-- ----
	-- <!--Call the internal drop set functionality and generate the event-->åȺǽθƤӽФȻݤ
	-- ----
	perform dropSet_int(p_set_id);
	return  createEvent(&#39;_schemadoc&#39;, &#39;DROP_SET&#39;, 
			p_set_id);
end;
</programlisting>
      </para>
    </section>

<!-- Function dropset_int( integer ) -->
    <section id="function.dropset-int-integer"
             xreflabel="schemadocdropset_int( integer )">
      <title id="function.dropset-int-integer-title">
       dropset_int( integer )
      </title>
      <titleabbrev id="function.dropset-int-integer-titleabbrev">
       dropset_int( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       
        <programlisting>
declare
	p_set_id			alias for $1;
	v_tab_row			record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;
	
	-- ----
	-- <!--Restore all tables original triggers and rules and remove-->ƤΥơ֥θΥȥꥬȥ롼ꥹȥ
	-- <!--our replication stuff.-->ץꥱ
	-- ----
	for v_tab_row in select tab_id from sl_table
			where tab_set = p_set_id
			order by tab_id
	loop
		perform alterTableRestore(v_tab_row.tab_id);
		perform tableDropKey(v_tab_row.tab_id);
	end loop;

	-- ----
	-- <!--Remove all traces of the set configuration-->åȹƤΥȥ졼
	-- ----
	delete from sl_sequence
			where seq_set = p_set_id;
	delete from sl_table
			where tab_set = p_set_id;
	delete from sl_subscribe
			where sub_set = p_set_id;
	delete from sl_setsync
			where ssy_setid = p_set_id;
	delete from sl_set
			where set_id = p_set_id;

	-- <!--Regenerate sl_listen since we revised the subscriptions-->ɤ򹹿 sl_listen 
	perform RebuildListenEntries();

	return p_set_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function droptrigger( integer, name ) -->
    <section id="function.droptrigger-integer-name"
             xreflabel="schemadocdroptrigger( integer, name )">
      <title id="function.droptrigger-integer-name-title">
       droptrigger( integer, name )
      </title>
      <titleabbrev id="function.droptrigger-integer-name-titleabbrev">
       droptrigger( integer, name )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       dropTrigger (trig_tabid, trig_tgname)

<!--Submits DROP_TRIGGER event to indicate that trigger trig_tgname on
replicated table trig_tabid WILL be disabled.-->
ʣ줿ơ֥ trig_tabid Υȥꥬ trig_tgname ưʤ褦ˤ줿򼨤 DROP_TRIGGER ݤȯԤ롣

        <programlisting>
declare
	p_trig_tabid		alias for $1;
	p_trig_tgname		alias for $2;
begin
	perform dropTrigger_int(p_trig_tabid, p_trig_tgname);
	return  createEvent(&#39;_schemadoc&#39;, &#39;DROP_TRIGGER&#39;,
			p_trig_tabid, p_trig_tgname);
end;
</programlisting>
      </para>
    </section>

<!-- Function droptrigger_int( integer, name ) -->
    <section id="function.droptrigger-int-integer-name"
             xreflabel="schemadocdroptrigger_int( integer, name )">
      <title id="function.droptrigger-int-integer-name-title">
       droptrigger_int( integer, name )
      </title>
      <titleabbrev id="function.droptrigger-int-integer-name-titleabbrev">
       droptrigger_int( integer, name )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       dropTrigger_int (trig_tabid, trig_tgname)

<!--Processes DROP_TRIGGER event to make sure that trigger trig_tgname on
replicated table trig_tabid IS disabled.-->
ʣ줿ơ֥ trig_tabid Υȥꥬ trigger trig_tgname ̵ˤʤäɤǧ DROP_TRIGGER ݤ롣
 
        <programlisting>
declare
	p_trig_tabid		alias for $1;
	p_trig_tgname		alias for $2;
	v_tab_altered		boolean;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Get the current table status (altered or not)-->ߤΥơ֥ξ֤ѹƤ褦ޤ
	-- ----
	select tab_altered into v_tab_altered
			from sl_table where tab_id = p_trig_tabid;
	if not found then
		-- ----
		-- <!--Not found is no hard error here, because that might-->Ĥʤȸ顼ϤǤϸޤ
		-- <!--mean that we are not subscribed to that set-->Τʤ顢ΥåȤɤƤޤ
		-- ----
		return 0;
	end if;

	-- ----
	-- <!--If the table is modified for replication, restore the original state-->ʣΤơ֥뤬ѹƤСξ֤ꥹȥ
	-- ----
	if v_tab_altered then
		perform alterTableRestore(p_trig_tabid);
	end if;

	-- ----
	-- <!--Remove the entry from sl_trigger-->sl_trigger 饨ȥ
	-- ----
	delete from sl_trigger
			where trig_tabid = p_trig_tabid
			  and trig_tgname = p_trig_tgname;

	-- ----
	-- <!--Put the table back into replicated state if it was-->⤷äʤơ֥ʣ줿֤᤹
	-- ----
	if v_tab_altered then
		perform alterTableForReplication(p_trig_tabid);
	end if;

	return p_trig_tabid;
end;
</programlisting>
      </para>
    </section>

<!-- Function enablenode( integer ) -->
    <section id="function.enablenode-integer"
             xreflabel="schemadocenablenode( integer )">
      <title id="function.enablenode-integer-title">
       enablenode( integer )
      </title>
      <titleabbrev id="function.enablenode-integer-titleabbrev">
       enablenode( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       no_id - <!--Node ID #-->Ρɼֹ̻

<!--Generate the ENABLE_NODE event for node no_id-->Ρ no_id Ф ENABLE_NODE ݤ
        <programlisting>
declare
	p_no_id			alias for $1;
	v_local_node_id		int4;
	v_node_row		record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that we are the node to activate and that we are-->䤿ϳưŪˤʤΡɤǤ뤬
	-- <!--currently disabled.-->ߤưʤ褦ˤʤäƤθ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);
	select * into v_node_row
			from sl_node
			where no_id = p_no_id
			for update;
	if not found then 
		raise exception &#39;Slony-I: node % not found&#39;, p_no_id;
	end if;
	if v_node_row.no_active then
		raise exception &#39;Slony-I: node % is already active&#39;, p_no_id;
	end if;

	-- ----
	-- <!--Activate this node and generate the ENABLE_NODE event-->ΥΡɤENABLE_NODE ݤ
	-- ----
	perform enableNode_int (p_no_id);
	return  createEvent(&#39;_schemadoc&#39;, &#39;ENABLE_NODE&#39;,
									p_no_id);
end;
</programlisting>
      </para>
    </section>

<!-- Function enablenode_int( integer ) -->
    <section id="function.enablenode-int-integer"
             xreflabel="schemadocenablenode_int( integer )">
      <title id="function.enablenode-int-integer-title">
       enablenode_int( integer )
      </title>
      <titleabbrev id="function.enablenode-int-integer-titleabbrev">
       enablenode_int( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       no_id - <!--Node ID #-->Ρɼֹ̻

<!--Internal function to process the ENABLE_NODE event for node no_id-->Ρ no_id Ф ENABLE_NODE ݤؿ

        <programlisting>
declare
	p_no_id			alias for $1;
	v_local_node_id		int4;
	v_node_row		record;
	v_sub_row		record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that the node is inactive-->ΡɤưƤʤθ
	-- ----
	select * into v_node_row
			from sl_node
			where no_id = p_no_id
			for update;
	if not found then 
		raise exception &#39;Slony-I: node % not found&#39;, p_no_id;
	end if;
	if v_node_row.no_active then
		return p_no_id;
	end if;

	-- ----
	-- <!--Activate the node and generate sl_confirm status rows for it.-->ΡɤѤ sl_confirm ơԤ
	-- ----
	update sl_node
			set no_active = &#39;t&#39;
			where no_id = p_no_id;
	insert into sl_confirm
			(con_origin, con_received, con_seqno)
			select no_id, p_no_id, 0 from sl_node
				where no_id != p_no_id
				and no_active;
	insert into sl_confirm
			(con_origin, con_received, con_seqno)
			select p_no_id, no_id, 0 from sl_node
				where no_id != p_no_id
				and no_active;

	-- ----
	-- <!--Generate ENABLE_SUBSCRIPTION events for all sets that-->ȯƤ礦ɺưΡɤǹɤ줿
	-- <!--origin here and are subscribed by the just enabled node.-->ƤΥåȤФ ENABLE_SUBSCRIPTION ݤ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);
	for v_sub_row in select SUB.sub_set, SUB.sub_provider from
			sl_set S,
			sl_subscribe SUB
			where S.set_origin = v_local_node_id
			and S.set_id = SUB.sub_set
			and SUB.sub_receiver = p_no_id
			for update of S
	loop
		perform enableSubscription (v_sub_row.sub_set,
				v_sub_row.sub_provider, p_no_id);
	end loop;

	return p_no_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function enablesubscription( integer, integer, integer ) -->
    <section id="function.enablesubscription-integer-integer-integer"
             xreflabel="schemadocenablesubscription( integer, integer, integer )">
      <title id="function.enablesubscription-integer-integer-integer-title">
       enablesubscription( integer, integer, integer )
      </title>
      <titleabbrev id="function.enablesubscription-integer-integer-integer-titleabbrev">
       enablesubscription( integer, integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       enableSubscription (sub_set, sub_provider, sub_receiver)

<!--Indicates that sub_receiver intends subscribing to set sub_set from
sub_provider.  Work is all done by the internal function
enableSubscription_int (sub_set, sub_provider, sub_receiver).-->
sub_provider  å sub_set  sub_receiver ɤߤƤ뤳Ȥ򼨤ޤȤؿ enableSubscription_int (sub_set, sub_provider, sub_receiver) ˤԤޤ

        <programlisting>
declare
	p_sub_set		alias for $1;
	p_sub_provider		alias for $2;
	p_sub_receiver		alias for $3;
begin
	return  enableSubscription_int (p_sub_set, 
			p_sub_provider, p_sub_receiver);
end;
</programlisting>
      </para>
    </section>

<!-- Function enablesubscription_int( integer, integer, integer ) -->
    <section id="function.enablesubscription-int-integer-integer-integer"
             xreflabel="schemadocenablesubscription_int( integer, integer, integer )">
      <title id="function.enablesubscription-int-integer-integer-integer-title">
       enablesubscription_int( integer, integer, integer )
      </title>
      <titleabbrev id="function.enablesubscription-int-integer-integer-integer-titleabbrev">
       enablesubscription_int( integer, integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
         <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       enableSubscription_int (sub_set, sub_provider, sub_receiver)

<!--Internal function to enable subscription of node sub_receiver to set
sub_set via node sub_provider.

slon does most of the work; all we need do here is to remember that it
happened.  The function updates sl_subscribe, indicating that the
subscription has become active.-->
node sub_provider ˤꥻå sub_set ФΡ sub_receiver ɤǤ褦ˤؿ

slon ϤκȤؤɤԤޤΤ褦ʤȤȸȤФƤɬפޤؿϹưͭˤʤä򼨺 sl_subscribe 򹹿ޤ

        <programlisting>
declare
	p_sub_set		alias for $1;
	p_sub_provider		alias for $2;
	p_sub_receiver		alias for $3;
	v_n			int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--The real work is done in the replication engine. All-->ºݤλŻʣ󥸥ǹԤޤ
	-- <!--we have to do here is remembering that it happened.-->䤿ܤϤФƤǤ
	-- ----

	-- ----
	-- <!--Well, not only ... we might be missing an important event here-->Ǥ̵  פʻݤ˺Ƥ뤫⤷ޤ
	-- ----
	if not exists (select true from sl_path
			where pa_server = p_sub_provider
			and pa_client = p_sub_receiver)
	then
		insert into sl_path
				(pa_server, pa_client, pa_conninfo, pa_connretry)
				values 
				(p_sub_provider, p_sub_receiver, 
				&#39;&lt;event pending&gt;&#39;, 10);
	end if;

	update sl_subscribe
			set sub_active = &#39;t&#39;
			where sub_set = p_sub_set
			and sub_receiver = p_sub_receiver;
	get diagnostics v_n = row_count;
	if v_n = 0 then
		insert into sl_subscribe
				(sub_set, sub_provider, sub_receiver,
				sub_forward, sub_active)
				values
				(p_sub_set, p_sub_provider, p_sub_receiver,
				false, true);
	end if;

	-- Rewrite sl_listen table
	perform RebuildListenEntries();

	return p_sub_set;
end;
</programlisting>
      </para>
    </section>

<!-- Function failednode( integer, integer ) -->
    <section id="function.failednode-integer-integer"
             xreflabel="schemadocfailednode( integer, integer )">
      <title id="function.failednode-integer-integer-title">
       failednode( integer, integer )
      </title>
      <titleabbrev id="function.failednode-integer-integer-titleabbrev">
       failednode( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Initiate failover from failed_node to backup_node.  This function must be called on all nodes, 
and then waited for the restart of all node daemons.-->
       failed_node to backup_node ե륪Ф򳫻ϤޤδؿƤΥΡɤǸƤФʤФʤ餺ƤΥΡɤΥǡκƵưԵʤФʤޤ

        <programlisting>
declare
	p_failed_node		alias for $1;
	p_backup_node		alias for $2;
	v_row			record;
	v_row2			record;
	v_n			int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--All consistency checks first-->Ƥΰθ
	-- <!--Check that every system that has a path to the failed node-->ξΡɤؤηϩƤΥƥबͭƤ뤫θ
	-- <!--also has a path to the backup node.-->Ʊ˥ХååץΡɤؤηϩ뤫⸡
	-- ----
	for v_row in select P.pa_client
			from sl_path P
			where P.pa_server = p_failed_node
				and P.pa_client &lt;&gt; p_backup_node
				and not exists (select true from sl_path PP
							where PP.pa_server = p_backup_node
								and PP.pa_client = P.pa_client)
	loop
		raise exception &#39;Slony-I: cannot failover - node % has no path to the backup node&#39;,
				v_row.pa_client;
	end loop;

	-- ----
	-- Check all sets originating on the failed node
	-- ----
	for v_row in select set_id
			from sl_set
			where set_origin = p_failed_node
	loop
		-- ----
		-- <!--Check that the backup node is subscribed to all sets-->ξΡɤΥꥸǤƤΥåȤ
		-- <!--that origin on the failed node-->ХååץΡɤɤƤ뤫θ
		-- ----
		select into v_row2 sub_forward, sub_active
				from sl_subscribe
				where sub_set = v_row.set_id
					and sub_receiver = p_backup_node;
		if not found then
			raise exception &#39;Slony-I: cannot failover - node % is not subscribed to set %&#39;,
					p_backup_node, v_row.set_id;
		end if;

		-- ----
		-- <!--Check that the subscription is active-->ưͭθ
		-- ----
		if not v_row2.sub_active then
			raise exception &#39;Slony-I: cannot failover - subscription for set % is not active&#39;,
					v_row.set_id;
		end if;

		-- ----
		-- <!--If there are other subscribers, the backup node needs to-->¾˹ɥΡɤСХååץΡɤ
		-- <!--be a forwarder too.-->ȯΡɤˤʤɬפƱˤޤ
		-- ----
		select into v_n count(*)
				from sl_subscribe
				where sub_set = v_row.set_id
					and sub_receiver &lt;&gt; p_backup_node;
		if v_n &gt; 0 and not v_row2.sub_forward then
			raise exception &#39;Slony-I: cannot failover - node % is not a forwarder of set %&#39;,
					p_backup_node, v_row.set_id;
		end if;
	end loop;

	-- ----
	-- <!--Terminate all connections of the failed node the hard way-->ξΡɤƤ³
	-- ----
	perform terminateNodeConnections(
			&#39;_schemadoc_Node_&#39; || p_failed_node);

-- <!--Note that the following code should all become obsolete in the wake-->
   RebuildListenEntries() ͭˤʤäƤаʲΥɤϻȤʤʤ
-- <!--of the availability of RebuildListenEntries()...-->
   ФƤƤ
if false then
	-- ----
	-- <!--Let every node that listens for something on the failed node-->ξΡɤ鲿ƻ뤷ƤƤΥΡɤ
	-- <!--listen for that on the backup node instead.-->ȤƥХååץΡɾΤƻ뤹褦ˤޤ
	-- ----
	for v_row in select * from sl_listen
			where li_provider = p_failed_node
				and li_receiver &lt;&gt; p_backup_node
	loop
		perform storeListen_int(v_row.li_origin,
				p_backup_node, v_row.li_receiver);
	end loop;

	-- ----
	-- <!--Let the backup node listen for all events where the-->ξΡɤƻ뤷ƤƤλݤ
	-- <!--failed node did listen for it.-->ХååץΡɤƻ뤹ͤˤޤ
	-- ----
	for v_row in select li_origin, li_provider
			from sl_listen
			where li_receiver = p_failed_node
				and li_provider &lt;&gt; p_backup_node
	loop
		perform storeListen_int(v_row.li_origin,
				v_row.li_provider, p_backup_node);
	end loop;

	-- ----
	-- <!--Remove all sl_listen entries that receive anything from the-->ξΡɤ鲿Ǥ
	-- <!--failed node.-->Ƥ sl_listen ȥޤ
	-- ----
	delete from sl_listen
			where li_provider = p_failed_node
				or li_receiver = p_failed_node;
end if;

	-- ----
	-- <!--Move the sets-->åȤΰư
	-- ----
	for v_row in select S.set_id, (select count(*)
					from sl_subscribe SUB
					where S.set_id = SUB.sub_set
						and SUB.sub_receiver &lt;&gt; p_backup_node
						and SUB.sub_provider = p_failed_node)
					as num_direct_receivers 
			from sl_set S
			where S.set_origin = p_failed_node
			for update
	loop
		-- ----
		-- <!--If the backup node is the only direct subscriber ...-->ХååץΡɤͣľܹɥΡɤݤ
		-- ----
		if v_row.num_direct_receivers = 0 then
raise notice &#39;failedNode: set % has no other direct receivers - move now&#39;, v_row.set_id;
			-- ----
			-- <!--backup_node is the only direct subscriber, move the set-->ХååץΡɤͣľܹɥΡɤǡåȤΤ˰ưޤ
			-- <!--right now. On the backup node itself that includes restoring-->ХååץΡɾǤ켫ȤϡκȤ򤷤ޤ
			-- <!--all user mode triggers, removing the protection trigger,-->ƤΥ桼⡼ɤΥȥꥬΥꥹȥ
			-- <!--adding the log trigger, removing the subscription and the-->ȥꥬɲáɤκ
			-- <!--obsolete setsync status.-->줯ʤä setsync ơκ
			-- ----
			if p_backup_node = getLocalNodeId(&#39;_schemadoc&#39;) then
				for v_row2 in select * from sl_table
						where tab_set = v_row.set_id
				loop
					perform alterTableRestore(v_row2.tab_id);
				end loop;
			end if;

			update sl_set set set_origin = p_backup_node
					where set_id = v_row.set_id;

			if p_backup_node = getLocalNodeId(&#39;_schemadoc&#39;) then
				delete from sl_setsync
						where ssy_setid = v_row.set_id;

				for v_row2 in select * from sl_table
						where tab_set = v_row.set_id
				loop
					perform alterTableForReplication(v_row2.tab_id);
				end loop;
			end if;

			delete from sl_subscribe
					where sub_set = v_row.set_id
						and sub_receiver = p_backup_node;
		else
raise notice &#39;failedNode: set % has other direct receivers - change providers only&#39;, v_row.set_id;
			-- ----
			-- <!--Backup node is not the only direct subscriber. This-->ХååץΡɤͣľܹɥΡɤǤϤޤ
			-- <!--means that at this moment, we redirect all direct-->̣ϡλƤľܹɥΡɤХååץΡɤ
			-- <!--subscribers to receive from the backup node, and the-->褦˥쥯ȤХååץΡɤ켫Ȥ
			-- <!--backup node itself to receive from another one.-->¾褦ˤޤ
			-- <!--The admin utility will wait for the slon engine to-->桼ƥƥ slon 󥸥󤬺ƵưޤԵ
			-- <!--restart and then call failedNode2() on the node with-->ΤȺǹ̤ SYNC ͭƤΡɾ failedNode2()
			-- <!--the highest SYNC and redirect this to it on-->ƤӽФƤǥХååץΡɾ
			-- <!--backup node later.-->쥯Ȥޤ
			-- ----
			update sl_subscribe
					set sub_provider = (select min(SS.sub_receiver)
							from sl_subscribe SS
							where SS.sub_set = v_row.set_id
								and SS.sub_provider = p_failed_node
								and SS.sub_receiver &lt;&gt; p_backup_node
								and SS.sub_forward)
					where sub_set = v_row.set_id
						and sub_receiver = p_backup_node;
			update sl_subscribe
					set sub_provider = p_backup_node
					where sub_set = v_row.set_id
						and sub_provider = p_failed_node
						and sub_receiver &lt;&gt; p_backup_node;
		end if;
	end loop;

	-- <!--Rewrite sl_listen table-->sl_listen ơ֥ν񤭴
	perform RebuildListenEntries();

	-- ----
	-- <!--Make sure the node daemon will restart-->ΡɥǡκƵưγǧ
	-- ----
	notify &quot;_schemadoc_Restart&quot;;

	-- ----
	-- <!--That is it - so far.-->ȤꤢǤ
	-- ----
	return p_failed_node;
end;
</programlisting>
      </para>
    </section>

<!-- Function failednode2( integer, integer, integer, bigint, bigint ) -->
    <section id="function.failednode2-integer-integer-integer-bigint-bigint"
             xreflabel="schemadocfailednode2( integer, integer, integer, bigint, bigint )">
      <title id="function.failednode2-integer-integer-integer-bigint-bigint-title">
       failednode2( integer, integer, integer, bigint, bigint )
      </title>
      <titleabbrev id="function.failednode2-integer-integer-integer-bigint-bigint-titleabbrev">
       failednode2( integer, integer, integer, bigint, bigint )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION failedNode2 (failed_node, backup_node, set_id, ev_seqno, ev_seqfake)

<!--On the node that has the highest sequence number of the failed node,
fake the FAILED_NODE event.-->
ξΥΡɤǺǤ̤ΥֹͭƤΡɾ FAILED_NODE ݤ¤ޤ

        <programlisting>
declare
	p_failed_node		alias for $1;
	p_backup_node		alias for $2;
	p_set_id		alias for $3;
	p_ev_seqno		alias for $4;
	p_ev_seqfake		alias for $5;
	v_row			record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	select * into v_row
			from sl_event
			where ev_origin = p_failed_node
			and ev_seqno = p_ev_seqno;
	if not found then
		raise exception &#39;Slony-I: event %,% not found&#39;,
				p_failed_node, p_ev_seqno;
	end if;

	insert into sl_event
			(ev_origin, ev_seqno, ev_timestamp,
			ev_minxid, ev_maxxid, ev_xip,
			ev_type, ev_data1, ev_data2, ev_data3)
			values 
			(p_failed_node, p_ev_seqfake, CURRENT_TIMESTAMP,
			v_row.ev_minxid, v_row.ev_maxxid, v_row.ev_xip,
			&#39;FAILOVER_SET&#39;, p_failed_node::text, p_backup_node::text,
			p_set_id::text);
	insert into sl_confirm
			(con_origin, con_received, con_seqno, con_timestamp)
			values
			(p_failed_node, getLocalNodeId(&#39;_schemadoc&#39;),
			p_ev_seqfake, CURRENT_TIMESTAMP);
	notify &quot;_schemadoc_Event&quot;;
	notify &quot;_schemadoc_Confirm&quot;;
	notify &quot;_schemadoc_Restart&quot;;

	perform failoverSet_int(p_failed_node,
			p_backup_node, p_set_id);

	return p_ev_seqfake;
end;
</programlisting>
      </para>
    </section>

<!-- Function failoverset_int( integer, integer, integer ) -->
    <section id="function.failoverset-int-integer-integer-integer"
             xreflabel="schemadocfailoverset_int( integer, integer, integer )">
      <title id="function.failoverset-int-integer-integer-integer-title">
       failoverset_int( integer, integer, integer )
      </title>
      <titleabbrev id="function.failoverset-int-integer-integer-integer-titleabbrev">
       failoverset_int( integer, integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION failoverSet_int (failed_node, backup_node, set_id)

<!--Finish failover for one set.-->1 ĤΥåȤФե륪Фνλ
        <programlisting>
declare
	p_failed_node		alias for $1;
	p_backup_node		alias for $2;
	p_set_id			alias for $3;
	v_row				record;
	v_last_sync			int8;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Change the origin of the set now to the backup node.-->åȤΥꥸХååץΡɤѹޤ
	-- <!--On the backup node this includes changing all the-->ХååץΡɾǡˤƤΥȥꥬȾ㳲ɻߤ
	-- <!--trigger and protection stuff-->ޤߤޤ
	-- ----
	if p_backup_node = getLocalNodeId(&#39;_schemadoc&#39;) then
		for v_row in select * from sl_table
				where tab_set = p_set_id
		loop
			perform alterTableRestore(v_row.tab_id);
		end loop;

		delete from sl_setsync
				where ssy_setid = p_set_id;
		delete from sl_subscribe
				where sub_set = p_set_id
					and sub_receiver = p_backup_node;
		update sl_set
				set set_origin = p_backup_node
				where set_id = p_set_id;

		for v_row in select * from sl_table
				where tab_set = p_set_id
		loop
			perform alterTableForReplication(v_row.tab_id);
		end loop;
	else
		delete from sl_subscribe
				where sub_set = p_set_id
					and sub_receiver = p_backup_node;
		update sl_set
				set set_origin = p_backup_node
				where set_id = p_set_id;
	end if;

	-- <!--Rewrite sl_listen table-->sl_listen ơ֥ν񤭴
	perform RebuildListenEntries();

	-- ----
	-- <!--If we are a subscriber of the set ourself, change our-->ȤåȤιɥΡɤξ硢setsync ơ
	-- <!--setsync status to reflect the new set origin.-->åȥꥸȿǤ褦ѹޤ
	-- ----
	if exists (select true from sl_subscribe
			where sub_set = p_set_id
				and sub_receiver = getLocalNodeId(
						&#39;_schemadoc&#39;))
	then
		delete from sl_setsync
				where ssy_setid = p_set_id;

		select coalesce(max(ev_seqno), 0) into v_last_sync
				from sl_event
				where ev_origin = p_backup_node
					and ev_type = &#39;SYNC&#39;;
		if v_last_sync &gt; 0 then
			insert into sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					select p_set_id, p_backup_node, v_last_sync,
					ev_minxid, ev_maxxid, ev_xip, NULL
					from sl_event
					where ev_origin = p_backup_node
						and ev_seqno = v_last_sync;
		else
			insert into sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					values (p_set_id, p_backup_node, &#39;0&#39;,
					&#39;0&#39;, &#39;0&#39;, &#39;&#39;, NULL);
		end if;
				
	end if;

	return p_failed_node;
end;
</programlisting>
      </para>
    </section>

<!-- Function forwardconfirm( integer, integer, bigint, timestamp without time zone ) -->
    <section id="function.forwardconfirm-integer-integer-bigint-timestamp-without-time-zone"
             xreflabel="schemadocforwardconfirm( integer, integer, bigint, timestamp without time zone )">
      <title id="function.forwardconfirm-integer-integer-bigint-timestamp-without-time-zone-title">
       forwardconfirm( integer, integer, bigint, timestamp without time zone )
      </title>
      <titleabbrev id="function.forwardconfirm-integer-integer-bigint-timestamp-without-time-zone-titleabbrev">
       forwardconfirm( integer, integer, bigint, timestamp without time zone )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       forwardConfirm (p_con_origin, p_con_received, p_con_seqno, p_con_timestamp)

<!--Confirms (recorded in sl_confirm) that items from p_con_origin up to
p_con_seqno  have been received by node p_con_received as of
p_con_timestamp, and raises an event to forward this confirmation.-->
p_con_origin  p_con_seqno ޤǤιܤ p_con_timestamp ǥΡ p_con_received Ǽ졢γǧФݤΩ夲Ȥsl_confirm ˵Ͽ줿˳ǧԤޤ

        <programlisting>
declare
	p_con_origin            alias for $1;
	p_con_received		alias for $2;
	p_con_seqno		alias for $3;
	p_con_timestamp		alias for $4;
	v_max_seqno		bigint;
begin
	select into v_max_seqno coalesce(max(con_seqno), 0)
			from sl_confirm
			where con_origin = p_con_origin
			and con_received = p_con_received;
	if v_max_seqno &lt; p_con_seqno then
		insert into sl_confirm 
				(con_origin, con_received, con_seqno, con_timestamp)
				values (p_con_origin, p_con_received, p_con_seqno,
					p_con_timestamp);
		notify &quot;_schemadoc_Confirm&quot;;
		v_max_seqno = p_con_seqno;
	end if;

	return v_max_seqno;
end;
</programlisting>
      </para>
    </section>

<!-- Function generate_sync_event( interval ) -->
    <section id="function.generate-sync-event-interval"
             xreflabel="schemadocgenerate_sync_event( interval )">
      <title id="function.generate-sync-event-interval-title">
       generate_sync_event( interval )
      </title>
      <titleabbrev id="function.generate-sync-event-interval-titleabbrev">
       generate_sync_event( interval )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Generate a sync event if there has not been one in 30 seconds.-->
       30 ð 1 Ĥ sync ݤ̵硢sync ݤޤ
        <programlisting>
declare
	p_interval     alias for $1;
	v_node_row     record;

BEGIN
	select 1 into v_node_row from sl_event 
       	  where ev_type = &#39;SYNC&#39; and ev_origin = getLocalNodeId(&#39;schemadoc&#39;)
          and ev_timestamp &gt; now() - p_interval limit 1;
	if not found then
		-- If there has been no SYNC in the last interval, then push one
		perform createEvent(&#39;schemadoc&#39;, &#39;SYNC&#39;, NULL);
		return 1;
	else
		return 0;
	end if;
end;
</programlisting>
      </para>
    </section>

<!-- Function getlocalnodeid( name ) -->
    <section id="function.getlocalnodeid-name"
             xreflabel="schemadocgetlocalnodeid( name )">
      <title id="function.getlocalnodeid-name-title">
       getlocalnodeid( name )
      </title>
      <titleabbrev id="function.getlocalnodeid-name-titleabbrev">
       getlocalnodeid( name )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Returns the node ID of the node being serviced on the local database-->
       ǡ١ǥӥƤΡɤΥΡɼ̻Ҥ֤ޤ
        <programlisting>_Slony_I_getLocalNodeId</programlisting>
      </para>
    </section>

<!-- Function getmoduleversion(  ) -->
    <section id="function.getmoduleversion"
             xreflabel="schemadocgetmoduleversion(  )">
      <title id="function.getmoduleversion-title">
       getmoduleversion(  )
      </title>
      <titleabbrev id="function.getmoduleversion-titleabbrev">
       getmoduleversion(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Returns the compiled-in version number of the Slony-I shared object-->
        Slony-I ֥ͭȤΥѥ뤵줿Сֹ֤ޤ
        <programlisting>_Slony_I_getModuleVersion</programlisting>
      </para>
    </section>

<!-- Function getsessionrole( name ) -->
    <section id="function.getsessionrole-name"
             xreflabel="schemadocgetsessionrole( name )">
      <title id="function.getsessionrole-name-title">
       getsessionrole( name )
      </title>
      <titleabbrev id="function.getsessionrole-name-titleabbrev">
       getsessionrole( name )
      </titleabbrev>

      <para>
       <segmentedlist>
         <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--not yet documented-->̤ɥȲƤޤ
        <programlisting>_Slony_I_getSessionRole</programlisting>
      </para>
    </section>

<!-- Function initializelocalnode( integer, text ) -->
    <section id="function.initializelocalnode-integer-text"
             xreflabel="schemadocinitializelocalnode( integer, text )">
      <title id="function.initializelocalnode-integer-text-title">
       initializelocalnode( integer, text )
      </title>
      <titleabbrev id="function.initializelocalnode-integer-text-titleabbrev">
       initializelocalnode( integer, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       no_id - Node ID #
no_comment - <!--Human-oriented comment-->ͼˤ륳

<--Initializes the new node,-->Ρ no_id ν
        <programlisting>
declare
	p_local_node_id		alias for $1;
	p_comment		alias for $2;
	v_old_node_id		int4;
	v_first_log_no		int4;
	v_event_seq		int8;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Make sure this node is uninitialized or got reset-->ΥΡɤϽƤʤꥻåȤ뤫γǧ
	-- ----
	select last_value::int4 into v_old_node_id from sl_local_node_id;
	if v_old_node_id != -1 then
		raise exception &#39;Slony-I: This node is already initialized&#39;;
	end if;

	-- ----
	-- <!--Set sl_local_node_id to the requested value and add our-->sl_local_node_id ׵ͤꤷ
	-- <!--own system to sl_node.-->ʬΥƥ  sl_node ˲äޤ
	-- ----
	perform setval(&#39;sl_local_node_id&#39;, p_local_node_id);
	perform setval(&#39;sl_rowid_seq&#39;, 
			p_local_node_id::int8 * &#39;1000000000000000&#39;::int8);
	perform storeNode_int (p_local_node_id, p_comment, false);
	
	return p_local_node_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function lockedset(  ) -->
    <section id="function.lockedset"
             xreflabel="schemadoclockedset(  )">
      <title id="function.lockedset-title">
       lockedset(  )
      </title>
      <titleabbrev id="function.lockedset-titleabbrev">
       lockedset(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>&quot;trigger&quot;</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Trigger function to prevent modifications to a table before and after a moveSet()-->
        moveSet() ˥ơ֥Фѹɻߤȥꥬؿ

        <programlisting>_Slony_I_lockedSet</programlisting>
      </para>
    </section>

<!-- Function lockset( integer ) -->
    <section id="function.lockset-integer"
             xreflabel="schemadoclockset( integer )">
      <title id="function.lockset-integer-title">
       lockset( integer )
      </title>
      <titleabbrev id="function.lockset-integer-titleabbrev">
       lockset( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       lockSet(set_id)

<!--Add a special trigger to all tables of a set that disables access to
it.-->
˥Ǥʤ륻åȤƤΥơ֥̤ʥȥꥬɲäޤ

        <programlisting>
declare
	p_set_id			alias for $1;
	v_local_node_id			int4;
	v_set_row			record;
	v_tab_row			record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that the set exists and that we are the origin-->åȤ¸ߤʬꥸ̤å
	-- <!--and that it is not already locked.-->ʤȤγǧ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);
	select * into v_set_row from sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_set_id;
	end if;
	if v_set_row.set_origin &lt;&gt; v_local_node_id then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				p_set_id;
	end if;
	if v_set_row.set_locked notnull then
		raise exception &#39;Slony-I: set % is already locked&#39;, p_set_id;
	end if;

	-- ----
	-- <!--Place the lockedSet trigger on all tables in the set.-->åƤΥơ֥ lockedSet ȥꥬ֤롣
	-- ----
	for v_tab_row in select T.tab_id,
			slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
			slon_quote_brute(PGC.relname) as tab_fqname
			from sl_table T,
				&quot;pg_catalog&quot;.pg_class PGC, &quot;pg_catalog&quot;.pg_namespace PGN
			where T.tab_set = p_set_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid
			order by tab_id
	loop
		execute &#39;create trigger &quot;_schemadoc_lockedset_&#39; || 
				v_tab_row.tab_id || 
				&#39;&quot; before insert or update or delete on &#39; ||
				v_tab_row.tab_fqname || &#39; for each row execute procedure
				lockedSet (&#39;&#39;_schemadoc&#39;&#39;);&#39;;
	end loop;

	-- ----
	-- <!--Remember our snapshots xmax as for the set locking-->åȤΥåݤФƥʥåץå xmax פƤ
	-- ----
	update sl_set
			set set_locked = getMaxXid()
			where set_id = p_set_id;

	return p_set_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function logtrigger(  ) -->
    <section id="function.logtrigger"
             xreflabel="schemadoclogtrigger(  )">
      <title id="function.logtrigger-title">
       logtrigger(  )
      </title>
      <titleabbrev id="function.logtrigger-titleabbrev">
       logtrigger(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>&quot;trigger&quot;</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--This is the trigger that is executed on the origin node that causes
updates to be recorded in sl_log_1/sl_log_2.-->
       ϡ sl_log_1/sl_log_2 ˵Ͽ褦ˤ륪ꥸΡɤǼ¹ԤȥꥬǤ

        <programlisting>_Slony_I_logTrigger</programlisting>
      </para>
    </section>

<!-- Function mergeset( integer, integer ) -->
    <section id="function.mergeset-integer-integer"
             xreflabel="schemadocmergeset( integer, integer )">
      <title id="function.mergeset-integer-integer-title">
       mergeset( integer, integer )
      </title>
      <titleabbrev id="function.mergeset-integer-integer-titleabbrev">
       mergeset( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Generate MERGE_SET event to request that sets be merged together.-->
       åȤʻ礵褦׵᤹ MERGE_SET ݤ

<!--Both sets must exist, and originate on the same node.  They must be
subscribed by the same set of nodes.-->
ΥåȤɬ¸ߤƱΥΡɤȯʤФʤޤ󡣤ϥΡɤƱΥåȤˤɤɬפޤ

        <programlisting>
declare
	p_set_id			alias for $1;
	p_add_id			alias for $2;
	v_origin			int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;
	
	-- ----
	-- <!--Check that both sets exist and originate here-->2 ĤΥåȤ¸ߤȯθ
	-- ----
	if p_set_id = p_add_id then
		raise exception &#39;Slony-I: merged set ids cannot be identical&#39;;
	end if;
	select set_origin into v_origin from sl_set
			where set_id = p_set_id;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_set_id;
	end if;
	if v_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				p_set_id;
	end if;

	select set_origin into v_origin from sl_set
			where set_id = p_add_id;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_add_id;
	end if;
	if v_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				p_add_id;
	end if;

	-- ----
	-- <!--Check that both sets are subscribed by the same set of nodes-->2 ĤΥåȤΡɤƱåȤǹɤθ
	-- ----
	if exists (select true from sl_subscribe SUB1
				where SUB1.sub_set = p_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from sl_subscribe SUB2
						where SUB2.sub_set = p_add_id))
	then
		raise exception &#39;Slony-I: subscriber lists of set % and % are different&#39;,
				p_set_id, p_add_id;
	end if;

	if exists (select true from sl_subscribe SUB1
				where SUB1.sub_set = p_add_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from sl_subscribe SUB2
						where SUB2.sub_set = p_set_id))
	then
		raise exception &#39;Slony-I: subscriber lists of set % and % are different&#39;,
				p_add_id, p_set_id;
	end if;

	-- ----
	-- <!--Create a SYNC event, merge the sets, create a MERGE_SET event-->SYNC κåȤʻ硢MERGE_SET ݤκ
	-- ----
	perform createEvent(&#39;_schemadoc&#39;, &#39;SYNC&#39;, NULL);
	perform mergeSet_int(p_set_id, p_add_id);
	return  createEvent(&#39;_schemadoc&#39;, &#39;MERGE_SET&#39;, 
			p_set_id, p_add_id);
end;
</programlisting>
      </para>
    </section>

<!-- Function mergeset_int( integer, integer ) -->
    <section id="function.mergeset-int-integer-integer"
             xreflabel="schemadocmergeset_int( integer, integer )">
      <title id="function.mergeset-int-integer-integer-title">
       mergeset_int( integer, integer )
      </title>
      <titleabbrev id="function.mergeset-int-integer-integer-titleabbrev">
       mergeset_int( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       mergeSet_int(set_id, add_id) - <!--Perform MERGE_SET event, merging all objects from 
set add_id into set set_id.-->MERGE_SET ݤμ¹ԡset add_id  set set_id ƤΥ֥Ȥʻ礷ޤ

        <programlisting>
declare
	p_set_id			alias for $1;
	p_add_id			alias for $2;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;
	
	update sl_sequence
			set seq_set = p_set_id
			where seq_set = p_add_id;
	update sl_table
			set tab_set = p_set_id
			where tab_set = p_add_id;
	delete from sl_subscribe
			where sub_set = p_add_id;
	delete from sl_setsync
			where ssy_setid = p_add_id;
	delete from sl_set
			where set_id = p_add_id;

	return p_set_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function moveset( integer, integer ) -->
    <section id="function.moveset-integer-integer"
             xreflabel="schemadocmoveset( integer, integer )">
      <title id="function.moveset-integer-integer-title">
       moveset( integer, integer )
      </title>
      <titleabbrev id="function.moveset-integer-integer-titleabbrev">
       moveset( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       moveSet(set_id, new_origin)

<!--Generate MOVE_SET event to request that the origin for set set_id be moved to node new_origin-->
å set_id Ф륪ꥸ󤬥Ρ new_origin ˰ư褦׵᤹ MOVE_SET ݤ

        <programlisting>
declare
	p_set_id			alias for $1;
	p_new_origin			alias for $2;
	v_local_node_id			int4;
	v_set_row			record;
	v_sub_row			record;
	v_sync_seqno			int8;
	v_lv_row			record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that the set is locked and that this locking-->åȤ˥åݤ졢ΥåϤʤ
	-- <!--happened long enough ago.-->ݤ줿θ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);
	select * into v_set_row from sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_set_id;
	end if;
	if v_set_row.set_origin &lt;&gt; v_local_node_id then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				p_set_id;
	end if;
	if v_set_row.set_locked isnull then
		raise exception &#39;Slony-I: set % is not locked&#39;, p_set_id;
	end if;
	if v_set_row.set_locked &gt; getMinXid() then
		raise exception &#39;Slony-I: cannot move set % yet, transactions &lt; % are still in progress&#39;,
				p_set_id, v_set_row.set_locked;
	end if;

	-- ----
	-- <!--Unlock the set-->åȤΥåβ
	-- ----
	perform unlockSet(p_set_id);

	-- ----
	-- <!--Check that the new_origin is an active subscriber of the set-->new_origin ϥåȤͭʹɥΡɤθ
	-- ----
	select * into v_sub_row from sl_subscribe
			where sub_set = p_set_id
			and sub_receiver = p_new_origin;
	if not found then
		raise exception &#39;Slony-I: set % is not subscribed by node %&#39;,
				p_set_id, p_new_origin;
	end if;
	if not v_sub_row.sub_active then
		raise exception &#39;Slony-I: subsctiption of node % for set % is inactive&#39;,
				p_new_origin, p_set_id;
	end if;

	-- ----
	-- <!--Reconfigure everything-->Ƥκƹ
	-- ----
	perform moveSet_int(p_set_id, v_local_node_id,
			p_new_origin);

	perform RebuildListenEntries();

	-- ----
	-- <!--At this time we hold access exclusive locks for every table-->λǥåƤΥơ֥˥¾åαޤ
	-- <!--in the set. But we did move the set to the new origin, so the-->åȤ򿷵ꥸΡɤ˰ưä
	-- <!--createEvent() we are doing now will not record the sequences.-->ԤäƤ createEvent() ϥ󥹤Ͽޤ
	-- ----
	v_sync_seqno := createEvent(&#39;_schemadoc&#39;, &#39;SYNC&#39;);
	insert into sl_seqlog 
			(seql_seqid, seql_origin, seql_ev_seqno, seql_last_value)
			select seq_id, v_local_node_id, v_sync_seqno, seq_last_value
			from sl_seqlastvalue
			where seq_set = p_set_id;
					
	-- ----
	-- <!--Finally we generate the real event-->ǽŪ˼ºݤλݤޤ
	-- ----
	return createEvent(&#39;_schemadoc&#39;, &#39;MOVE_SET&#39;, 
			p_set_id, v_local_node_id, p_new_origin);
end;
</programlisting>
      </para>
    </section>

<!-- Function moveset_int( integer, integer, integer ) -->
    <section id="function.moveset-int-integer-integer-integer"
             xreflabel="schemadocmoveset_int( integer, integer, integer )">
      <title id="function.moveset-int-integer-integer-integer-title">
       moveset_int( integer, integer, integer )
      </title>
      <titleabbrev id="function.moveset-int-integer-integer-integer-titleabbrev">
       moveset_int( integer, integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       moveSet(set_id, old_origin, new_origin)

<!--Process MOVE_SET event to request that the origin for set set_id be
moved from old_origin to node new_origin-->
å set_id Ф륪ꥸ old_origin Ρ new_origin ذư褦׵᤹ MOVE_SET ݤ
        <programlisting>
declare
	p_set_id			alias for $1;
	p_old_origin			alias for $2;
	p_new_origin			alias for $3;
	v_local_node_id			int4;
	v_tab_row			record;
	v_sub_row			record;
	v_sub_node			int4;
	v_sub_last			int4;
	v_sub_next			int4;
	v_last_sync			int8;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥åμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Get our local node ID-->ʬΥΡɼ̻Ҥ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);

	-- ----
	-- <!--If we are the old or new origin of the set, we need to-->䤿åȤε⤷ϿꥸΡɤǤСޤǽ
	-- <!--remove the log trigger from all tables first.-->ƤΥơ֥뤫ȥꥬžޤ
	-- ----
	if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
		for v_tab_row in select tab_id from sl_table
				where tab_set = p_set_id
				order by tab_id
		loop
			perform alterTableRestore(v_tab_row.tab_id);
		end loop;
	end if;

	-- On the new origin, raise an event - ACCEPT_SET
	if v_local_node_id = p_new_origin then
		-- Find the event number from the origin
		select max(ev_seqno) as seqno into v_sub_row 
			from sl_event
			where ev_type = &#39;MOVE_SET&#39; and
			  ev_data1 = p_set_id and
			  ev_data2 = p_old_origin and
			  ev_data3 = p_new_origin and
			  ev_origin = p_old_origin;
		
		perform createEvent(&#39;_schemadoc&#39;, &#39;ACCEPT_SET&#39;, 
			p_set_id, p_old_origin, p_new_origin, v_sub_row.seqno);
	end if;

	-- ----
	-- <!--Next we have to reverse the subscription path-->˹ɷϩȿžɬפޤ
	-- ----
	v_sub_last = p_new_origin;
	select sub_provider into v_sub_node
			from sl_subscribe
			where sub_set = p_set_id
			and sub_receiver = p_new_origin;
	if not found then
		raise exception &#39;Slony-I: subscription path broken in moveSet_int&#39;;
	end if;
	while v_sub_node &lt;&gt; p_old_origin loop
		-- ----
		-- <!--Tracing node by node, the old receiver is now in-->Ρ 1  1 ĥȥ졼ǡ쥷ХΡɤ v_sub_last ˤꡢ
		-- <!--v_sub_last and the old provider is in v_sub_node.-->ץХΡɤ  v_sub_node ˤޤ
		-- ----

		-- ----
		-- <!--Get the current provider of this node as next-->ȿžϢΥץХФѤΡ
		-- <!--and change the provider to the previous one in-->ƥץХѹȤƤΥΡɤθߤ
		-- <!--the reverse chain.-->ץХޤ
		-- ----
		select sub_provider into v_sub_next
				from sl_subscribe
				where sub_set = p_set_id
					and sub_receiver = v_sub_node
				for update;
		if not found then
			raise exception &#39;Slony-I: subscription path broken in moveSet_int&#39;;
		end if;
		update sl_subscribe
				set sub_provider = v_sub_last
				where sub_set = p_set_id
					and sub_receiver = v_sub_node;

		v_sub_last = v_sub_node;
		v_sub_node = v_sub_next;
	end loop;

	-- ----
	-- <!--This includes creating a subscription for the old origin-->ϵ쥪ꥸФɤκޤߤޤ
	-- ----
	insert into sl_subscribe
			(sub_set, sub_provider, sub_receiver,
			sub_forward, sub_active)
			values (p_set_id, v_sub_last, p_old_origin, true, true);
	if v_local_node_id = p_old_origin then
		select coalesce(max(ev_seqno), 0) into v_last_sync 
				from sl_event
				where ev_origin = p_new_origin
					and ev_type = &#39;SYNC&#39;;
		if v_last_sync &gt; 0 then
			insert into sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					select p_set_id, p_new_origin, v_last_sync,
					ev_minxid, ev_maxxid, ev_xip, NULL
					from sl_event
					where ev_origin = p_new_origin
						and ev_seqno = v_last_sync;
		else
			insert into sl_setsync
					(ssy_setid, ssy_origin, ssy_seqno,
					ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
					values (p_set_id, p_new_origin, &#39;0&#39;,
					&#39;0&#39;, &#39;0&#39;, &#39;&#39;, NULL);
		end if;
	end if;

	-- ----
	-- <!--Now change the ownership of the set.-->ǥåȤνͭԤѹޤ
	-- ----
	update sl_set
			set set_origin = p_new_origin
			where set_id = p_set_id;

	-- ----
	-- <!--On the new origin, delete the obsolete setsync information-->ꥸǡȤʤʤä setsync 
	-- <!--and the subscription.-->ɤޤ
	-- ----
	if v_local_node_id = p_new_origin then
		delete from sl_setsync
				where ssy_setid = p_set_id;
	else
		if v_local_node_id &lt;&gt; p_old_origin then
			--
			-- <!--On every other node, change the setsync so that it will-->¾ƤΥΡɾǡꥸ󤫤ǸΤ줿 sync  
			-- <!--pick up from the new origins last known sync.-->뤿 setsync ѹޤ
			--
			delete from sl_setsync
					where ssy_setid = p_set_id;
			select coalesce(max(ev_seqno), 0) into v_last_sync
					from sl_event
					where ev_origin = p_new_origin
						and ev_type = &#39;SYNC&#39;;
			if v_last_sync &gt; 0 then
				insert into sl_setsync
						(ssy_setid, ssy_origin, ssy_seqno,
						ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
						select p_set_id, p_new_origin, v_last_sync,
						ev_minxid, ev_maxxid, ev_xip, NULL
						from sl_event
						where ev_origin = p_new_origin
							and ev_seqno = v_last_sync;
			else
				insert into sl_setsync
						(ssy_setid, ssy_origin, ssy_seqno,
						ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
						values (p_set_id, p_new_origin, &#39;0&#39;,
						&#39;0&#39;, &#39;0&#39;, &#39;&#39;, NULL);
			end if;
		end if;
	end if;
	delete from sl_subscribe
			where sub_set = p_set_id
			and sub_receiver = p_new_origin;

	-- <!--Regenerate sl_listen since we revised the subscriptions
	perform RebuildListenEntries();-->ɤ RebuildListenEntries() ¹Ԥ褦˹Τ sl_listen ޤ

	-- ----
	-- <!--If we are the new or old origin, we have to-->⤷䤿⤷ϵ쥪ꥸǤСƤΥơ֥
	-- <!--put all the tables into altered state again.-->Ƥѹ줿֤ˤʤФʤޤ
	-- ----
	if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then
		for v_tab_row in select tab_id from sl_table
				where tab_set = p_set_id
				order by tab_id
		loop
			perform alterTableForReplication(v_tab_row.tab_id);
		end loop;
	end if;

	return p_set_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function rebuildlistenentries(  ) -->
    <section id="function.rebuildlistenentries"
             xreflabel="schemadocrebuildlistenentries(  )">
      <title id="function.rebuildlistenentries-title">
       rebuildlistenentries(  )
      </title>
      <titleabbrev id="function.rebuildlistenentries-titleabbrev">
       rebuildlistenentries(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       RebuildListenEntries(p_provider, p_receiver)

<!--Invoked by various subscription and path modifying functions, this
rewrites the sl_listen entries, adding in all the ones required to
allow communications between nodes in the Slony-I cluster.-->
ޤޤʹɤȷϩѹؿˤ굯ư졢ϡSlony-I 饹ΥΡɴ̿ǽˤΤɬפƤɲä sl_listen ȥ񤭴ޤ 
        <programlisting>
declare
	v_row			record;
begin
	-- <!--First remove the entire configuration-->ǽ˹Τޤ
	delete from sl_listen;

	-- <!--The loop over every possible pair of origin, receiver-->Ƥβǽ᤿ꥸȥ쥷ФȤ߹碌롼פޤ
	for v_row in select N1.no_id as origin, N2.no_id as receiver
			from sl_node N1, sl_node N2
			where N1.no_id &lt;&gt; N2.no_id
	loop
		perform RebuildListenEntriesOne(v_row.origin, v_row.receiver);
	end loop;

	return 0;
end;
</programlisting>
      </para>
    </section>

<!-- Function rebuildlistenentriesone( integer, integer ) -->
    <section id="function.rebuildlistenentriesone-integer-integer"
             xreflabel="schemadocrebuildlistenentriesone( integer, integer )">
      <title id="function.rebuildlistenentriesone-integer-integer-title">
       rebuildlistenentriesone( integer, integer )
      </title>
      <titleabbrev id="function.rebuildlistenentriesone-integer-integer-titleabbrev">
       rebuildlistenentriesone( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       RebuildListenEntriesOne(p_origin, p_receiver)

Rebuilding of sl_listen entries for one origin, receiver pair.
        <programlisting>
declare
	p_origin		alias for $1;
	p_receiver		alias for $2;
	v_row			record;
begin
	-- 1. <!--If the receiver is subscribed to any set from the origin,-->쥷Фꥸ󤫤ɤʥåȤǤɤΤǤ
	--    <!--listen on the same provider(s).-->ƱΥץХʣġ˾ƻ뤷ޤ
	for v_row in select distinct sub_provider
			from sl_subscribe, sl_set,
				sl_path
			where sub_set = set_id
			and set_origin = p_origin
			and sub_receiver = p_receiver
			and sub_provider = pa_server
			and sub_receiver = pa_client
	loop
		perform storeListen_int(p_origin, 
				v_row.sub_provider, p_receiver);
	end loop;
	if found then
		return 1;
	end if;

	-- 2. <!--If the receiver has a direct path to the provider,-->⤷쥷ФץХľܷϩͭƤ
	--    <!--use that.-->Ȥޤ
	if exists (select true
			from sl_path
			where pa_server = p_origin
			and pa_client = p_receiver)
	then
		perform storeListen_int(p_origin, p_origin, p_receiver);
		return 1;
	end if;

	-- 3. <!--Listen on every node that is either provider for the-->쥷ФФץХ⤷ϡץХȤƥ쥷ФѤƤ
	--    <!--receiver or is using the receiver as provider (follow the-->ƤΥΡɤƻ뤷ޤ̾ιɥ롼Ȥ˽ä
	--    <!--normal subscription routes).-->ˡ
	for v_row in select distinct provider from (
			select sub_provider as provider
					from sl_subscribe
					where sub_receiver = p_receiver
			union
			select sub_receiver as provider
					from sl_subscribe
					where sub_provider = p_receiver
					and exists (select true from sl_path
								where pa_server = sub_receiver
								and pa_client = sub_provider)
			) as S
	loop
		perform storeListen_int(p_origin,
				v_row.provider, p_receiver);
	end loop;
	if found then
		return 1;
	end if;

	-- 4. <!--If all else fails - meaning there are no subscriptions to-->⤷ƤԤǤСĤޤϩ䤿ƳƤɤ¸ߤʤ
	--    <!--guide us to the right path - use every node we have a path-->ץХȤƷϩͭƤƤΥΡɤѤޤ
	--    <!--to as provider. This normally only happens when the cluster-->λ̾說饹ۤ줿⤷ϿΡɤɲä줿Τߵޤ
	--    <!--is built or a new node added. This brute force fallback-->ηä̵ñʽʥ֥롼ȥեإƥϤ⤷äƲǽǤС
	--    <!--ensures that events will propagate if possible at all.-->ݤŤݾڤޤ
	for v_row in select pa_server as provider
			from sl_path
			where pa_client = p_receiver
	loop
		perform storeListen_int(p_origin, 
				v_row.provider, p_receiver);
	end loop;
	if found then
		return 1;
	end if;

	return 0;
end;
</programlisting>
      </para>
    </section>

<!-- Function sequencelastvalue( text ) -->
    <section id="function.sequencelastvalue-text"
             xreflabel="schemadocsequencelastvalue( text )">
      <title id="function.sequencelastvalue-text-title">
       sequencelastvalue( text )
      </title>
      <titleabbrev id="function.sequencelastvalue-text-titleabbrev">
       sequencelastvalue( text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       
        <programlisting>
declare
	p_seqname	alias for $1;
	v_seq_row	record;
begin
	for v_seq_row in execute &#39;select last_value from &#39; || p_seqname
	loop
		return v_seq_row.last_value;
	end loop;

	-- <!--not reached-->̤ãޤ
end;
</programlisting>
      </para>
    </section>

<!-- Function sequencesetvalue( integer, integer, bigint, bigint ) -->
    <section id="function.sequencesetvalue-integer-integer-bigint-bigint"
             xreflabel="schemadocsequencesetvalue( integer, integer, bigint, bigint )">
      <title id="function.sequencesetvalue-integer-integer-bigint-bigint-title">
       sequencesetvalue( integer, integer, bigint, bigint )
      </title>
      <titleabbrev id="function.sequencesetvalue-integer-integer-bigint-bigint-titleabbrev">
       sequencesetvalue( integer, integer, bigint, bigint )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       sequenceSetValue (seq_id, seq_origin, ev_seqno, last_value)
<!--Set sequence seq_id to have new value last_value.-->
 seq_id 򿷵 last_value ꤷޤ

        <programlisting>
declare
	p_seq_id			alias for $1;
	p_seq_origin			alias for $2;
	p_ev_seqno			alias for $3;
	p_last_value			alias for $4;
	v_fqname			text;
begin
	-- ----
	-- <!--Get the sequences fully qualified name-->󥹤δ̾Fully Qualified Nameˤ
	-- ----
	select slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
			slon_quote_brute(PGC.relname) into v_fqname
		from sl_sequence SQ,
			&quot;pg_catalog&quot;.pg_class PGC, &quot;pg_catalog&quot;.pg_namespace PGN
		where SQ.seq_id = p_seq_id
			and SQ.seq_reloid = PGC.oid
			and PGC.relnamespace = PGN.oid;
	if not found then
		raise exception &#39;Slony-I: sequence % not found&#39;, p_seq_id;
	end if;

	-- ----
	-- <!--Update it to the new value-->ͤ˹
	-- ----
	execute &#39;select setval(&#39;&#39;&#39; || v_fqname ||
			&#39;&#39;&#39;, &#39;&#39;&#39; || p_last_value || &#39;&#39;&#39;)&#39;;

	insert into sl_seqlog
			(seql_seqid, seql_origin, seql_ev_seqno, seql_last_value)
			values (p_seq_id, p_seq_origin, p_ev_seqno, p_last_value);

	return p_seq_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function setaddsequence( integer, integer, text, text ) -->
    <section id="function.setaddsequence-integer-integer-text-text"
             xreflabel="schemadocsetaddsequence( integer, integer, text, text )">
      <title id="function.setaddsequence-integer-integer-text-text-title">
       setaddsequence( integer, integer, text, text )
      </title>
      <titleabbrev id="function.setaddsequence-integer-integer-text-text-titleabbrev">
       setaddsequence( integer, integer, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       setAddSequence (set_id, seq_id, seq_fqname, seq_comment)

<!--On the origin node for set set_id, add sequence seq_fqname to the
replication set, and raise SET_ADD_SEQUENCE to cause this to replicate
to subscriber nodes.-->
å set_id Ф륪ꥸΡɤǡ seq_fqname ʣåȤɲä줬ɥΡɤʣ褦 SET_ADD_SEQUENCE Ω夲ޤ

        <programlisting>
declare
	p_set_id			alias for $1;
	p_seq_id			alias for $2;
	p_fqname			alias for $3;
	p_seq_comment		alias for $4;
	v_set_origin		int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that we are the origin of the set-->䤿åȤΥꥸ󤫤θ
	-- ----
	select set_origin into v_set_origin
			from sl_set
			where set_id = p_set_id;
	if not found then
		raise exception &#39;Slony-I: setAddSequence(): set % not found&#39;, p_set_id;
	end if;
	if v_set_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: setAddSequence(): set % has remote origin&#39;, p_set_id;
	end if;

	if exists (select true from sl_subscribe
			where sub_set = p_set_id)
	then
		raise exception &#39;Slony-I: cannot add sequence to currently subscribed set %&#39;,
				p_set_id;
	end if;

	-- ----
	-- <!--Add the sequence to the set and generate the SET_ADD_SEQUENCE event-->󥹤򥻥åȤɲäSET_ADD_SEQUENCE ݤޤ
	-- ----
	perform setAddSequence_int(p_set_id, p_seq_id, p_fqname,
			p_seq_comment);
	return  createEvent(&#39;_schemadoc&#39;, &#39;SET_ADD_SEQUENCE&#39;,
			p_set_id, p_seq_id, p_fqname, p_seq_comment);
end;
</programlisting>
      </para>
    </section>

<!-- Function setaddsequence_int( integer, integer, text, text ) -->
    <section id="function.setaddsequence-int-integer-integer-text-text"
             xreflabel="schemadocsetaddsequence_int( integer, integer, text, text )">
      <title id="function.setaddsequence-int-integer-integer-text-text-title">
       setaddsequence_int( integer, integer, text, text )
      </title>
      <titleabbrev id="function.setaddsequence-int-integer-integer-text-text-titleabbrev">
       setaddsequence_int( integer, integer, text, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       setAddSequence_int (set_id, seq_id, seq_fqname, seq_comment)

<!--This processes the SET_ADD_SEQUENCE event.  On remote nodes that
subscribe to set_id, add the sequence to the replication set.-->
 SET_ADD_SEQUENCE ݤޤ
        <programlisting>
declare
	p_set_id			alias for $1;
	p_seq_id			alias for $2;
	p_fqname			alias for $3;
	p_seq_comment			alias for $4;
	v_local_node_id			int4;
	v_set_origin			int4;
	v_sub_provider			int4;
	v_relkind			char;
	v_seq_reloid			oid;
	v_seq_relname			name;
	v_seq_nspname			name;
	v_sync_row			record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--For sets with a remote origin, check that we are subscribed -->֥ꥸΥåȤФơΥåȤ˻䤿ɤ
	-- <!--to that set. Otherwise we ignore the sequence because it might -->뤫θʤС䤿Υǡ١ˤ
	-- <!--not even exist in our database.-->¸ߤʤǤ餽Υ󥹤̵뤷ޤ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);
	select set_origin into v_set_origin
			from sl_set
			where set_id = p_set_id;
	if not found then
		raise exception &#39;Slony-I: setAddSequence_int(): set % not found&#39;,
				p_set_id;
	end if;
	if v_set_origin != v_local_node_id then
		select sub_provider into v_sub_provider
				from sl_subscribe
				where sub_set = p_set_id
				and sub_receiver = getLocalNodeId(&#39;_schemadoc&#39;);
		if not found then
			return 0;
		end if;
	end if;
	
	-- ----
	-- <!--Get the sequences OID and check that it is a sequence-->󥹥֥ȼ̻ҡOID)줬󥹤ݤ򸡺ޤ
	-- ----
	select PGC.oid, PGC.relkind, PGC.relname, PGN.nspname 
		into v_seq_reloid, v_relkind, v_seq_relname, v_seq_nspname
			from &quot;pg_catalog&quot;.pg_class PGC, &quot;pg_catalog&quot;.pg_namespace PGN
			where PGC.relnamespace = PGN.oid
			and slon_quote_input(p_fqname) = slon_quote_brute(PGN.nspname) ||
					&#39;.&#39; || slon_quote_brute(PGC.relname);
	if not found then
		raise exception &#39;Slony-I: setAddSequence_int(): sequence % not found&#39;, 
				p_fqname;
	end if;
	if v_relkind != &#39;S&#39; then
		raise exception &#39;Slony-I: setAddSequence_int(): % is not a sequence&#39;,
				p_fqname;
	end if;

	-- ----
	-- <!--Add the sequence to sl_sequence-->󥹤 sl_sequence ɲäޤ
	-- ----
	insert into sl_sequence
		(seq_id, seq_reloid, seq_relname, seq_nspname, seq_set, seq_comment) 
		values
		(p_seq_id, v_seq_reloid, v_seq_relname, v_seq_nspname,  p_set_id, p_seq_comment);

	-- ----
	-- <!--On the set origin, fake a sl_seqlog row for the last sync event-->åȥꥸǺǸ sync ݤˤ sl_seqlog Ԥ¤ޤ
	-- ----
	if v_set_origin = v_local_node_id then
		for v_sync_row in select coalesce (max(ev_seqno), 0) as ev_seqno
				from sl_event
				where ev_origin = v_local_node_id
					and ev_type = &#39;SYNC&#39;
		loop
			insert into sl_seqlog
					(seql_seqid, seql_origin, seql_ev_seqno, 
					seql_last_value) values
					(p_seq_id, v_local_node_id, v_sync_row.ev_seqno,
					sequenceLastValue(p_fqname));
		end loop;
	end if;

	return p_seq_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function setaddtable( integer, integer, text, name, text ) -->
    <section id="function.setaddtable-integer-integer-text-name-text"
             xreflabel="schemadocsetaddtable( integer, integer, text, name, text )">
      <title id="function.setaddtable-integer-integer-text-name-text-title">
       setaddtable( integer, integer, text, name, text )
      </title>
      <titleabbrev id="function.setaddtable-integer-integer-text-name-text-titleabbrev">
       setaddtable( integer, integer, text, name, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       setAddTable (set_id, tab_id, tab_fqname, tab_idxname, tab_comment)

<!--Add table tab_fqname to replication set on origin node, and generate
SET_ADD_TABLE event to allow this to propagate to other nodes.-->
ꥸΡɤǥơ֥ tab_fqname ʣåȤɲä¾ΥΡɤˤ줬Ť褦 SET_ADD_TABLE ݤޤ

<!--Note that the table id, tab_id, must be unique ACROSS ALL SETS.-->ƤΥåȤФƥơ֥뼱̻ҡtab_idϰդǤɬפ뤳ȤդƤ

        <programlisting>
declare
	p_set_id			alias for $1;
	p_tab_id			alias for $2;
	p_fqname			alias for $3;
	p_tab_idxname			alias for $4;
	p_tab_comment			alias for $5;
	v_set_origin			int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that we are the origin of the set-->䤿åȤΥꥸ󤫤ɤθ
	-- ----
	select set_origin into v_set_origin
			from sl_set
			where set_id = p_set_id;
	if not found then
		raise exception &#39;Slony-I: setAddTable(): set % not found&#39;, p_set_id;
	end if;
	if v_set_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: setAddTable(): set % has remote origin&#39;, p_set_id;
	end if;

	if exists (select true from sl_subscribe
			where sub_set = p_set_id)
	then
		raise exception &#39;Slony-I: cannot add table to currently subscribed set %&#39;,
				p_set_id;
	end if;

	-- ----
	-- <!--Add the table to the set and generate the SET_ADD_TABLE event-->åȤ˥ơ֥ɲäSET_ADD_TABLE ݤޤ
	-- ----
	perform setAddTable_int(p_set_id, p_tab_id, p_fqname,
			p_tab_idxname, p_tab_comment);
	return  createEvent(&#39;_schemadoc&#39;, &#39;SET_ADD_TABLE&#39;,
			p_set_id, p_tab_id, p_fqname,
			p_tab_idxname, p_tab_comment);
end;
</programlisting>
      </para>
    </section>

<!-- Function setaddtable_int( integer, integer, text, name, text ) -->
    <section id="function.setaddtable-int-integer-integer-text-name-text"
             xreflabel="schemadocsetaddtable_int( integer, integer, text, name, text )">
      <title id="function.setaddtable-int-integer-integer-text-name-text-title">
       setaddtable_int( integer, integer, text, name, text )
      </title>
      <titleabbrev id="function.setaddtable-int-integer-integer-text-name-text-titleabbrev">
       setaddtable_int( integer, integer, text, name, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       setAddTable_int (set_id, tab_id, tab_fqname, tab_idxname, tab_comment)

<!--This function processes the SET_ADD_TABLE event on remote nodes,
adding a table to replication if the remote node is subscribing to its
replication set.-->
δؿϱ֥Ρɤ SET_ADD_TABLE ݤ򡢤ʣåȤ֥ΡɤɤƤСʣơ֥ɲä򤷤ޤ

        <programlisting>
declare

	p_set_id		alias for $1;
	p_tab_id		alias for $2;
	p_fqname		alias for $3;
	p_tab_idxname		alias for $4;
	p_tab_comment		alias for $5;
	v_tab_relname		name;
	v_tab_nspname		name;
	v_local_node_id		int4;
	v_set_origin		int4;
	v_sub_provider		int4;
	v_relkind		char;
	v_tab_reloid		oid;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--For sets with a remote origin, check that we are subscribed -->֥ꥸΥåȤФơΥåȤ˻䤿ɤ
	-- <!--to that set. Otherwise we ignore the table because it might -->뤫θʤС䤿Υǡ١ˤ
	-- <!--not even exist in our database.-->¸ߤʤǤ餽Υơ̵֥뤷ޤ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);
	select set_origin into v_set_origin
			from sl_set
			where set_id = p_set_id;
	if not found then
		raise exception &#39;Slony-I: setAddTable_int(): set % not found&#39;,
				p_set_id;
	end if;
	if v_set_origin != v_local_node_id then
		select sub_provider into v_sub_provider
				from sl_subscribe
				where sub_set = p_set_id
				and sub_receiver = getLocalNodeId(&#39;_schemadoc&#39;);
		if not found then
			return 0;
		end if;
	end if;
	
	-- ----
	-- <!--Get the tables OID and check that it is a real table-->ơ֥륪֥ȼ̻ҡOID)줬ơ֥뤫ݤ򸡺ޤ
	-- ----
	select PGC.oid, PGC.relkind, PGC.relname, PGN.nspname into v_tab_reloid, v_relkind, v_tab_relname, v_tab_nspname
			from &quot;pg_catalog&quot;.pg_class PGC, &quot;pg_catalog&quot;.pg_namespace PGN
			where PGC.relnamespace = PGN.oid
			and slon_quote_input(p_fqname) = slon_quote_brute(PGN.nspname) ||
					&#39;.&#39; || slon_quote_brute(PGC.relname);
	if not found then
		raise exception &#39;Slony-I: setAddTable(): table % not found&#39;, 
				p_fqname;
	end if;
	if v_relkind != &#39;r&#39; then
		raise exception &#39;Slony-I: setAddTable(): % is not a regular table&#39;,
				p_fqname;
	end if;

	if not exists (select indexrelid
			from &quot;pg_catalog&quot;.pg_index PGX, &quot;pg_catalog&quot;.pg_class PGC
			where PGX.indrelid = v_tab_reloid
				and PGX.indexrelid = PGC.oid
				and PGC.relname = p_tab_idxname)
	then
		raise exception &#39;Slony-I: setAddTable(): table % has no index %&#39;,
				p_fqname, p_tab_idxname;
	end if;

	-- ----
	-- <!--Add the table to sl_table and create the trigger on it.-->ơ֥ sl_table ɲäξ˥ȥꥬޤ
	-- ----
	insert into sl_table
			(tab_id, tab_reloid, tab_relname, tab_nspname, 
			tab_set, tab_idxname, tab_altered, tab_comment) 
			values
			(p_tab_id, v_tab_reloid, v_tab_relname, v_tab_nspname,
			p_set_id, p_tab_idxname, false, p_tab_comment);
	perform alterTableForReplication(p_tab_id);

	return p_tab_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function setdropsequence( integer ) -->
    <section id="function.setdropsequence-integer"
             xreflabel="schemadocsetdropsequence( integer )">
      <title id="function.setdropsequence-integer-title">
       setdropsequence( integer )
      </title>
      <titleabbrev id="function.setdropsequence-integer-titleabbrev">
       setdropsequence( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       setDropSequence (seq_id)

<!--On the origin node for the set, drop sequence seq_id from replication
set, and raise SET_DROP_SEQUENCE to cause this to replicate to
subscriber nodes.-->
åȤФ륪ꥸΡɤʣåȤ饷 seq_id ɥΡɤˤʣ褦 SET_DROP_SEQUENCE Ω夲ޤ

        <programlisting>
declare
	p_seq_id		alias for $1;
	v_set_id		int4;
	v_set_origin		int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Determine set id for this sequence-->Υ󥹤Υåȼ̻Ҥ
	-- ----
	select seq_set into v_set_id from sl_sequence where seq_id = p_seq_id;

	-- ----
	-- <!--Ensure sequence exists-->󥹤¸ߤγξ
	-- ----
	if not found then
		raise exception &#39;Slony-I: setDropSequence_int(): sequence % not found&#39;,
			p_seq_id;
	end if;

	-- ----
	-- <!--Check that we are the origin of the set-->䤿åȤΥꥸ󤫤θ
	-- ----
	select set_origin into v_set_origin
			from sl_set
			where set_id = v_set_id;
	if not found then
		raise exception &#39;Slony-I: setDropSequence(): set % not found&#39;, v_set_id;
	end if;
	if v_set_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: setDropSequence(): set % has remote origin&#39;, v_set_id;
	end if;

	-- ----
	-- <!--Add the sequence to the set and generate the SET_ADD_SEQUENCE event-->󥹤򥻥åȤɲäSET_ADD_SEQUENCE ݤޤ
	-- ----
	perform setDropSequence_int(p_seq_id);
	return  createEvent(&#39;_schemadoc&#39;, &#39;SET_DROP_SEQUENCE&#39;,
			p_seq_id);
end;
</programlisting>
      </para>
    </section>

<!-- Function setdropsequence_int( integer ) -->
    <section id="function.setdropsequence-int-integer"
             xreflabel="schemadocsetdropsequence_int( integer )">
      <title id="function.setdropsequence-int-integer-title">
       setdropsequence_int( integer )
      </title>
      <titleabbrev id="function.setdropsequence-int-integer-titleabbrev">
       setdropsequence_int( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       setDropSequence_int (seq_id)

<!--This processes the SET_DROP_SEQUENCE event.  On remote nodes that
subscribe to the set containing sequence seq_id, drop the sequence
from the replication set.-->
SET_DROP_SEQUENCE ݤޤ seq_id ͭƤ륻åȤɤ֥ΡɤϡʣåȤ饷󥹤ޤ

        <programlisting>
declare
	p_seq_id		alias for $1;
	v_set_id		int4;
	v_local_node_id		int4;
	v_set_origin		int4;
	v_sub_provider		int4;
	v_relkind		char;
	v_sync_row		record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Determine set id for this sequence-->Υ󥹤Υåȼ̻Ҥ
	-- ----
	select seq_set into v_set_id from sl_sequence where seq_id = p_seq_id;

	-- ----
	-- <!--Ensure sequence exists-->󥹤¸ߤγξ
	-- ----
	if not found then
		return 0;
	end if;

	-- ----
	-- <!--For sets with a remote origin, check that we are subscribed -->֥ꥸΥåȤФơΥåȤ˻䤿ɤ
	-- <!--to that set. Otherwise we ignore the sequence because it might -->뤫θʤС䤿Υǡ١ˤ
	-- <!--not even exist in our database.-->¸ߤʤǤ餽Υ󥹤̵뤷ޤ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);
	select set_origin into v_set_origin
			from sl_set
			where set_id = v_set_id;
	if not found then
		raise exception &#39;Slony-I: setDropSequence_int(): set % not found&#39;,
				v_set_id;
	end if;
	if v_set_origin != v_local_node_id then
		select sub_provider into v_sub_provider
				from sl_subscribe
				where sub_set = v_set_id
				and sub_receiver = getLocalNodeId(&#39;_schemadoc&#39;);
		if not found then
			return 0;
		end if;
	end if;

	-- ----
	-- <!--drop the sequence from sl_sequence, sl_seqlog-->sl_sequencesl_seqlog 饷󥹤
	-- ----
	delete from sl_seqlog where seql_seqid = p_seq_id;
	delete from sl_sequence where seq_id = p_seq_id;

	return p_seq_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function setdroptable( integer ) -->
    <section id="function.setdroptable-integer"
             xreflabel="schemadocsetdroptable( integer )">
      <title id="function.setdroptable-integer-title">
       setdroptable( integer )
      </title>
      <titleabbrev id="function.setdroptable-integer-titleabbrev">
       setdroptable( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       setDropTable (tab_id)

<!--Drop table tab_id from set on origin node, and generate SET_DROP_TABLE
event to allow this to propagate to other nodes.-->

        <programlisting>
declare
	p_tab_id		alias for $1;
	v_set_id		int4;
	v_set_origin		int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

        -- ----
	-- <!--Determine the set_id-->set_id η
        -- ----
	select tab_set into v_set_id from sl_table where tab_id = p_tab_id;

	-- ----
	-- <!--Ensure table exists-->ơ֥¸ߤγξ
	-- ----
	if not found then
		raise exception &#39;Slony-I: setDropTable_int(): table % not found&#39;,
			p_tab_id;
	end if;

	-- ----
	-- <!--Check that we are the origin of the set-->䤿åȤΥꥸ󤫤θ
	-- ----
	select set_origin into v_set_origin
			from sl_set
			where set_id = v_set_id;
	if not found then
		raise exception &#39;Slony-I: setDropTable(): set % not found&#39;, v_set_id;
	end if;
	if v_set_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: setDropTable(): set % has remote origin&#39;, v_set_id;
	end if;

	-- ----
	-- <!--Drop the table from the set and generate the SET_ADD_TABLE event-->åȤơ֥SET_ADD_TABLE ݤ
	-- ----
	perform setDropTable_int(p_tab_id);
	return  createEvent(&#39;_schemadoc&#39;, &#39;SET_DROP_TABLE&#39;, p_tab_id);
end;
</programlisting>
      </para>
    </section>

<!-- Function setdroptable_int( integer ) -->
    <section id="function.setdroptable-int-integer"
             xreflabel="schemadocsetdroptable_int( integer )">
      <title id="function.setdroptable-int-integer-title">
       setdroptable_int( integer )
      </title>
      <titleabbrev id="function.setdroptable-int-integer-titleabbrev">
       setdroptable_int( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       setDropTable_int (tab_id)

<!--This function processes the SET_DROP_TABLE event on remote nodes,
dropping a table from replication if the remote node is subscribing to
its replication set.-->
δؿϱ֥Ρɤ SET_DROP_TABLE ݤ򡢤ʣåȤ֥ΡɤɤƤСʣơ֥ޤ

        <programlisting>
declare
	p_tab_id		alias for $1;
	v_set_id		int4;
	v_local_node_id		int4;
	v_set_origin		int4;
	v_sub_provider		int4;
	v_tab_reloid		oid;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

        -- ----
	-- <!--Determine the set_id-->set_id η
        -- ----
	select tab_set into v_set_id from sl_table where tab_id = p_tab_id;

	-- ----
	-- <!--Ensure table exists-->ơ֥¸ߤγξ
	-- ----
	if not found then
		return 0;
	end if;

	-- ----
	-- <!--For sets with a remote origin, check that we are subscribed -->֥ꥸΥåȤФơΥåȤ˻䤿ɤ
	-- <!--to that set. Otherwise we ignore the table because it might -->뤫θʤС䤿Υǡ١ˤ
	-- <!--not even exist in our database.-->¸ߤʤǤ餽Υơ̵֥뤷ޤ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);
	select set_origin into v_set_origin
			from sl_set
			where set_id = v_set_id;
	if not found then
		raise exception &#39;Slony-I: setDropTable_int(): set % not found&#39;,
				v_set_id;
	end if;
	if v_set_origin != v_local_node_id then
		select sub_provider into v_sub_provider
				from sl_subscribe
				where sub_set = v_set_id
				and sub_receiver = getLocalNodeId(&#39;_schemadoc&#39;);
		if not found then
			return 0;
		end if;
	end if;
	
	-- ----
	-- <!--Drop the table from sl_table and drop trigger from it.-->sl_table ơ֥ȥꥬޤ
	-- ----
	perform alterTableRestore(p_tab_id);
	perform tableDropKey(p_tab_id);
	delete from sl_table where tab_id = p_tab_id;
	return p_tab_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function setmovesequence( integer, integer ) -->
    <section id="function.setmovesequence-integer-integer"
             xreflabel="schemadocsetmovesequence( integer, integer )">
      <title id="function.setmovesequence-integer-integer-title">
       setmovesequence( integer, integer )
      </title>
      <titleabbrev id="function.setmovesequence-integer-integer-titleabbrev">
       setmovesequence( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       
        <programlisting>
declare
	p_seq_id                alias for $1;
	p_new_set_id		alias for $2;
	v_old_set_id		int4;
	v_origin		int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Get the sequences current set-->󥹤θߥåȤγ
	-- ----
	select seq_set into v_old_set_id from sl_sequence
			where seq_id = p_seq_id;
	if not found then
		raise exception &#39;Slony-I: sequence %d not found&#39;, p_seq_id;
	end if;
	
	-- ----
	-- <!--Check that both sets exist and originate here-->ΥåȤ¸ߤȯθ
	-- ----
	if p_new_set_id = v_old_set_id then
		raise exception &#39;Slony-I: set ids cannot be identical&#39;;
	end if;
	select set_origin into v_origin from sl_set
			where set_id = p_new_set_id;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_new_set_id;
	end if;
	if v_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				p_new_set_id;
	end if;

	select set_origin into v_origin from sl_set
			where set_id = v_old_set_id;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, v_old_set_id;
	end if;
	if v_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				v_old_set_id;
	end if;

	-- ----
	-- <!--Check that both sets are subscribed by the same set of nodes-->ΥåȤΡɤƱåȤˤɤΤθ
	-- ----
	if exists (select true from sl_subscribe SUB1
				where SUB1.sub_set = p_new_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from sl_subscribe SUB2
						where SUB2.sub_set = v_old_set_id))
	then
		raise exception &#39;Slony-I: subscriber lists of set % and % are different&#39;,
				p_new_set_id, v_old_set_id;
	end if;

	if exists (select true from sl_subscribe SUB1
				where SUB1.sub_set = v_old_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from sl_subscribe SUB2
						where SUB2.sub_set = p_new_set_id))
	then
		raise exception &#39;Slony-I: subscriber lists of set % and % are different&#39;,
				v_old_set_id, p_new_set_id;
	end if;

	-- ----
	-- <!--Change the set the sequence belongs to-->󥹤°륻åȤѹ
	-- ----
	perform setMoveSequence_int(p_seq_id, p_new_set_id);
	return  createEvent(&#39;_schemadoc&#39;, &#39;SET_MOVE_SEQUENCE&#39;, 
			p_seq_id, p_new_set_id);
end;
</programlisting>
      </para>
    </section>

<!-- Function setmovesequence_int( integer, integer ) -->
    <section id="function.setmovesequence-int-integer-integer"
             xreflabel="schemadocsetmovesequence_int( integer, integer )">
      <title id="function.setmovesequence-int-integer-integer-title">
       setmovesequence_int( integer, integer )
      </title>
      <titleabbrev id="function.setmovesequence-int-integer-integer-titleabbrev">
       setmovesequence_int( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       
        <programlisting>
declare
	p_seq_id			alias for $1;
	p_new_set_id			alias for $2;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;
	
	-- ----
	-- <!--Move the sequence to the new set-->åȤ˥󥹤ư
	-- ----
	update sl_sequence
			set seq_set = p_new_set_id
			where seq_id = p_seq_id;

	return p_seq_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function setmovetable( integer, integer ) -->
    <section id="function.setmovetable-integer-integer"
             xreflabel="schemadocsetmovetable( integer, integer )">
      <title id="function.setmovetable-integer-integer-title">
       setmovetable( integer, integer )
      </title>
      <titleabbrev id="function.setmovetable-integer-integer-titleabbrev">
       setmovetable( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--This processes the SET_MOVE_TABLE event.  The table is moved 
to the destination set.-->
SET_MOVE_TABLE ݤޤơ֥ϼåȤ˰ưޤ
        <programlisting>
declare
	p_tab_id			alias for $1;
	p_new_set_id			alias for $2;
	v_old_set_id			int4;
	v_origin			int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Get the tables current set-->ơ֥θߥåȤ
	-- ----
	select tab_set into v_old_set_id from sl_table
			where tab_id = p_tab_id;
	if not found then
		raise exception &#39;Slony-I: table %d not found&#39;, p_tab_id;
	end if;
	
	-- ----
	-- <!--Check that both sets exist and originate here-->ΥåȤ¸ߤ줿θ
	-- ----
	if p_new_set_id = v_old_set_id then
		raise exception &#39;Slony-I: set ids cannot be identical&#39;;
	end if;
	select set_origin into v_origin from sl_set
			where set_id = p_new_set_id;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_new_set_id;
	end if;
	if v_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				p_new_set_id;
	end if;

	select set_origin into v_origin from sl_set
			where set_id = v_old_set_id;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, v_old_set_id;
	end if;
	if v_origin != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				v_old_set_id;
	end if;

	-- ----
	-- <!--Check that both sets are subscribed by the same set of nodes-->ΥåȤΡɤƱåȤǹɤΤθ
	-- ----
	if exists (select true from sl_subscribe SUB1
				where SUB1.sub_set = p_new_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from sl_subscribe SUB2
						where SUB2.sub_set = v_old_set_id))
	then
		raise exception &#39;Slony-I: subscriber lists of set % and % are different&#39;,
				p_new_set_id, v_old_set_id;
	end if;

	if exists (select true from sl_subscribe SUB1
				where SUB1.sub_set = v_old_set_id
				and SUB1.sub_receiver not in (select SUB2.sub_receiver
						from sl_subscribe SUB2
						where SUB2.sub_set = p_new_set_id))
	then
		raise exception &#39;Slony-I: subscriber lists of set % and % are different&#39;,
				v_old_set_id, p_new_set_id;
	end if;

	-- ----
	-- <!--Change the set the table belongs to-->ơ֥뤬°륻åȤѹ
	-- ----
	perform createEvent(&#39;_schemadoc&#39;, &#39;SYNC&#39;, NULL);
	perform setMoveTable_int(p_tab_id, p_new_set_id);
	return  createEvent(&#39;_schemadoc&#39;, &#39;SET_MOVE_TABLE&#39;, 
			p_tab_id, p_new_set_id);
end;
</programlisting>
      </para>
    </section>

<!-- Function setmovetable_int( integer, integer ) -->
    <section id="function.setmovetable-int-integer-integer"
             xreflabel="schemadocsetmovetable_int( integer, integer )">
      <title id="function.setmovetable-int-integer-integer-title">
       setmovetable_int( integer, integer )
      </title>
      <titleabbrev id="function.setmovetable-int-integer-integer-titleabbrev">
       setmovetable_int( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       
        <programlisting>
declare
	p_tab_id			alias for $1;
	p_new_set_id			alias for $2;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υå
	-- ----
	lock table sl_config_lock;
	
	-- ----
	-- <!--Move the table to the new set-->åȤ˥ơ֥ư
	-- ----
	update sl_table
			set tab_set = p_new_set_id
			where tab_id = p_tab_id;

	return p_tab_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function setsessionrole( name, text ) -->
    <section id="function.setsessionrole-name-text"
             xreflabel="schemadocsetsessionrole( name, text )">
      <title id="function.setsessionrole-name-text-title">
       setsessionrole( name, text )
      </title>
      <titleabbrev id="function.setsessionrole-name-text-titleabbrev">
       setsessionrole( name, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--not yet documented-->̤ɥȲƤޤ
        <programlisting>_Slony_I_setSessionRole</programlisting>
      </para>
    </section>

<!-- Function slon_quote_brute( text ) -->
    <section id="function.slon-quote-brute-text"
             xreflabel="schemadocslon_quote_brute( text )">
      <title id="function.slon-quote-brute-text-title">
       slon_quote_brute( text )
      </title>
      <titleabbrev id="function.slon-quote-brute-text-titleabbrev">
       slon_quote_brute( text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Brutally quote the given text-->Ϳ줿ƥȤ̩˰Ѥޤ
        
        <programlisting>
declare	
    p_tab_fqname alias for $1;
    v_fqname text default &#39;&#39;;
begin
    v_fqname := &#39;&quot;&#39; || replace(p_tab_fqname,&#39;&quot;&#39;,&#39;\\&quot;&#39;) || &#39;&quot;&#39;;
    return v_fqname;
end;
</programlisting>
      </para>
    </section>

<!-- Function slon_quote_input( text ) -->
    <section id="function.slon-quote-input-text"
             xreflabel="schemadocslon_quote_input( text )">
      <title id="function.slon-quote-input-text-title">
       slon_quote_input( text )
      </title>
      <titleabbrev id="function.slon-quote-input-text-titleabbrev">
       slon_quote_input( text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--quote all words that aren&apos;t quoted yet-->̤ѤƤʤƤθդѤ롣
        <programlisting>
declare
    p_tab_fqname alias for $1;
    v_temp_fqname text default &#39;&#39;;
    v_pre_quoted text[] default &#39;{}&#39;;
    v_pre_quote_counter smallint default 0;
    v_count_fqname smallint default 0;
    v_fqname_split text[];
    v_quoted_fqname text default &#39;&#39;;
begin
    v_temp_fqname := p_tab_fqname;

    LOOP
	v_pre_quote_counter := v_pre_quote_counter + 1;
	v_pre_quoted[v_pre_quote_counter] := 
	    substring(v_temp_fqname from &#39;%#&quot;&quot;%&quot;#&quot;%&#39; for &#39;#&#39;);
	IF v_pre_quoted[v_pre_quote_counter] &lt;&gt; &#39;&#39; THEN
	    v_temp_fqname := replace(v_temp_fqname,
	        v_pre_quoted[v_pre_quote_counter], &#39;@&#39; ||
		v_pre_quote_counter);
	ELSE
	    EXIT;
	END IF;
    END LOOP;

    v_fqname_split := string_to_array(v_temp_fqname , &#39;.&#39;);
    v_count_fqname := array_upper (v_fqname_split, 1);

    FOR i in 1..v_count_fqname LOOP
        IF substring(v_fqname_split[i],1,1) = &#39;@&#39; THEN
            v_quoted_fqname := v_quoted_fqname || 
		v_pre_quoted[substring (v_fqname_split[i] from 2)::int];
        ELSE
            v_quoted_fqname := v_quoted_fqname || &#39;&quot;&#39; || 
		v_fqname_split[i] || &#39;&quot;&#39;;
        END IF;

        IF i &lt; v_count_fqname THEN
            v_quoted_fqname := v_quoted_fqname || &#39;.&#39; ;
        END IF;
    END LOOP;
	
    return v_quoted_fqname;
end;
</programlisting>
      </para>
    </section>

<!-- Function slonyversion(  ) -->
    <section id="function.slonyversion"
             xreflabel="schemadocslonyversion(  )">
      <title id="function.slonyversion-title">
       slonyversion(  )
      </title>
      <titleabbrev id="function.slonyversion-titleabbrev">
       slonyversion(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
      <!-- Returns the version number of the slony schema-->slony ޤΥСֹ֤ޤ 
        <programlisting>
begin
	return &#39;&#39;	|| slonyVersionMajor() || &#39;.&#39;
				|| slonyVersionMinor() || &#39;.&#39;
				|| slonyVersionPatchlevel();
end;
</programlisting>
      </para>
    </section>

<!-- Function slonyversionmajor(  ) -->
    <section id="function.slonyversionmajor"
             xreflabel="schemadocslonyversionmajor(  )">
      <title id="function.slonyversionmajor-title">
       slonyversionmajor(  )
      </title>
      <titleabbrev id="function.slonyversionmajor-titleabbrev">
       slonyversionmajor(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Returns the major version number of the slony schema-->slony ޤμץСֹ֤ޤ
        <programlisting>
begin
	return 1;
end;
</programlisting>
      </para>
    </section>

<!-- Function slonyversionminor(  ) -->
    <section id="function.slonyversionminor"
             xreflabel="schemadocslonyversionminor(  )">
      <title id="function.slonyversionminor-title">
       slonyversionminor(  )
      </title>
      <titleabbrev id="function.slonyversionminor-titleabbrev">
       slonyversionminor(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Returns the minor version number of the slony schema-->slony ޤŪСֹ֤ޤ
        <programlisting>
begin
	return 1;
end;
</programlisting>
      </para>
    </section>

<!-- Function slonyversionpatchlevel(  ) -->
    <section id="function.slonyversionpatchlevel"
             xreflabel="schemadocslonyversionpatchlevel(  )">
      <title id="function.slonyversionpatchlevel-title">
       slonyversionpatchlevel(  )
      </title>
      <titleabbrev id="function.slonyversionpatchlevel-titleabbrev">
       slonyversionpatchlevel(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Returns the version patch level of the slony schema-->slony ޤΥСΥѥå٥֤ޤ
        <programlisting>
begin
	return 0;
end;
</programlisting>
      </para>
    </section>

<!-- Function storelisten( integer, integer, integer ) -->
    <section id="function.storelisten-integer-integer-integer"
             xreflabel="schemadocstorelisten( integer, integer, integer )">
      <title id="function.storelisten-integer-integer-integer-title">
       storelisten( integer, integer, integer )
      </title>
      <titleabbrev id="function.storelisten-integer-integer-integer-titleabbrev">
       storelisten( integer, integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION storeListen (li_origin, li_provider, li_receiver)

<!--generate STORE_LISTEN event, indicating that receiver node li_receiver
listens to node li_provider in order to get messages coming from node
li_origin.-->
쥷ХΡ li_receiver Ρ li_origin Ϥå뤿ᡢΡ li_provider ƻ뤹򼨤 STORE_LISTEN ݤޤ
        <programlisting>
declare
	p_origin		alias for $1;
	p_provider		alias for $2;
	p_receiver		alias for $3;
begin
	return -1;

	perform storeListen_int (p_origin, p_provider, p_receiver);
	return  createEvent (&#39;_schemadoc&#39;, &#39;STORE_LISTEN&#39;,
			p_origin, p_provider, p_receiver);
end;
</programlisting>
      </para>
    </section>

<!-- Function storelisten_int( integer, integer, integer ) -->
    <section id="function.storelisten-int-integer-integer-integer"
             xreflabel="schemadocstorelisten_int( integer, integer, integer )">
      <title id="function.storelisten-int-integer-integer-integer-title">
       storelisten_int( integer, integer, integer )
      </title>
      <titleabbrev id="function.storelisten-int-integer-integer-integer-titleabbrev">
       storelisten_int( integer, integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION storeListen_int (li_origin, li_provider, li_receiver)

<!--Process STORE_LISTEN event, indicating that receiver node li_receiver
listens to node li_provider in order to get messages coming from node
li_origin.-->
쥷ХΡ li_receiver Ρ li_origin Ϥå뤿ᡢΡ li_provider ƻ뤹򼨤 STORE_LISTEN ݤޤ

        <programlisting>
declare
	p_li_origin		alias for $1;
	p_li_provider		alias for $2;
	p_li_receiver		alias for $3;
	v_exists		int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υå
	-- ----
	lock table sl_config_lock;

	select 1 into v_exists
			from sl_listen
			where li_origin = p_li_origin
			and li_provider = p_li_provider
			and li_receiver = p_li_receiver;
	if not found then
		-- ----
		-- <!--In case we receive STORE_LISTEN events before we know-->˴ϢΡɤդΤ STORE_LISTEN ݤ
		-- <!--about the nodes involved in this, we generate those nodes-->硢ΥΡɤ̤ʤΤȤ
		-- <!--as pending.-->ޤ
		-- ----
		if not exists (select 1 from sl_node
						where no_id = p_li_origin) then
			perform storeNode_int (p_li_origin, &#39;&lt;event pending&gt;&#39;, &#39;f&#39;);
		end if;
		if not exists (select 1 from sl_node
						where no_id = p_li_provider) then
			perform storeNode_int (p_li_provider, &#39;&lt;event pending&gt;&#39;, &#39;f&#39;);
		end if;
		if not exists (select 1 from sl_node
						where no_id = p_li_receiver) then
			perform storeNode_int (p_li_receiver, &#39;&lt;event pending&gt;&#39;, &#39;f&#39;);
		end if;

		insert into sl_listen
				(li_origin, li_provider, li_receiver) values
				(p_li_origin, p_li_provider, p_li_receiver);
	end if;

	return 0;
end;
</programlisting>
      </para>
    </section>

<!-- Function storenode( integer, text, boolean ) -->
    <section id="function.storenode-integer-text-boolean"
             xreflabel="schemadocstorenode( integer, text, boolean )">
      <title id="function.storenode-integer-text-boolean-title">
       storenode( integer, text, boolean )
      </title>
      <titleabbrev id="function.storenode-integer-text-boolean-titleabbrev">
       storenode( integer, text, boolean )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       no_id - <!--Node ID #-->Ρɼֹ̻
no_comment - <!--Human-oriented comment-->ͼˤ륳
no_spool - <!--Flag for virtual spool nodes-->ۥסΡɤФե饰

<!--Generate the STORE_NODE event for node no_id-->Ρ no_id Ф STORE_NODE ݤޤ
        <programlisting>
declare
	p_no_id			alias for $1;
	p_no_comment		alias for $2;
	p_no_spool		alias for $3;
	v_no_spool_txt		text;
begin
	if p_no_spool then
		v_no_spool_txt = &#39;t&#39;;
	else
		v_no_spool_txt = &#39;f&#39;;
	end if;
	perform storeNode_int (p_no_id, p_no_comment, p_no_spool);
	return  createEvent(&#39;_schemadoc&#39;, &#39;STORE_NODE&#39;,
									p_no_id, p_no_comment, v_no_spool_txt);
end;
</programlisting>
      </para>
    </section>

<!-- Function storenode_int( integer, text, boolean ) -->
    <section id="function.storenode-int-integer-text-boolean"
             xreflabel="schemadocstorenode_int( integer, text, boolean )">
      <title id="function.storenode-int-integer-text-boolean-title">
       storenode_int( integer, text, boolean )
      </title>
      <titleabbrev id="function.storenode-int-integer-text-boolean-titleabbrev">
       storenode_int( integer, text, boolean )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       no_id - <!--Node ID #-->Ρɼֹ̻
no_comment - <!--Human-oriented comment-->ͼˤ륳
no_spool - <!--Flag for virtual spool nodes-->ۥסΡɤФե饰

<!--Internal function to process the STORE_NODE event for node no_id-->Ρ no_id Ф STORE_NODE ݤؿ
        <programlisting>
declare
	p_no_id			alias for $1;
	p_no_comment		alias for $2;
	p_no_spool		alias for $3;
	v_old_row		record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υå
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check if the node exists-->Ρɤ¸ߤ򸡺
	-- ----
	select * into v_old_row
			from sl_node
			where no_id = p_no_id
			for update;
	if found then 
		-- ----
		-- <!--Node exists, update the existing row.-->Ρɤ¸ߤ¸ߤԤ򹹿
		-- ----
		update sl_node
				set no_comment = p_no_comment,
				no_spool = p_no_spool
				where no_id = p_no_id;
	else
		-- ----
		-- <!--New node, insert the sl_node row-->Ρɡsl_node Ԥ
		-- ----
		insert into sl_node
				(no_id, no_active, no_comment, no_spool) values
				(p_no_id, &#39;f&#39;, p_no_comment, p_no_spool);
	end if;

	return p_no_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function storepath( integer, integer, text, integer ) -->
    <section id="function.storepath-integer-integer-text-integer"
             xreflabel="schemadocstorepath( integer, integer, text, integer )">
      <title id="function.storepath-integer-integer-text-integer-title">
       storepath( integer, integer, text, integer )
      </title>
      <titleabbrev id="function.storepath-integer-integer-text-integer-titleabbrev">
       storepath( integer, integer, text, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION storePath (pa_server, pa_client, pa_conninfo, pa_connretry)

<!--Generate the STORE_PATH event indicating that node pa_client can
access node pa_server using DSN pa_conninfo-->
Ρ pa_client   DSN pa_conninfo ѤƥΡ pa_server ˥Ǥ褦˼ STORE_PATH ݤޤ
        <programlisting>
declare
	p_pa_server		alias for $1;
	p_pa_client		alias for $2;
	p_pa_conninfo		alias for $3;
	p_pa_connretry		alias for $4;
begin
	perform storePath_int(p_pa_server, p_pa_client,
			p_pa_conninfo, p_pa_connretry);
	return  createEvent(&#39;_schemadoc&#39;, &#39;STORE_PATH&#39;, 
			p_pa_server, p_pa_client, p_pa_conninfo, p_pa_connretry);
end;
</programlisting>
      </para>
    </section>

<!-- Function storepath_int( integer, integer, text, integer ) -->
    <section id="function.storepath-int-integer-integer-text-integer"
             xreflabel="schemadocstorepath_int( integer, integer, text, integer )">
      <title id="function.storepath-int-integer-integer-text-integer-title">
       storepath_int( integer, integer, text, integer )
      </title>
      <titleabbrev id="function.storepath-int-integer-integer-text-integer-titleabbrev">
       storepath_int( integer, integer, text, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       FUNCTION storePath (pa_server, pa_client, pa_conninfo, pa_connretry)

<!--Process the STORE_PATH event indicating that node pa_client can
access node pa_server using DSN pa_conninfo-->
Ρ pa_client   DSN pa_conninfo ѤƥΡ pa_server ˥Ǥ褦˼ STORE_PATH ݤޤ
        <programlisting>
declare
	p_pa_server		alias for $1;
	p_pa_client		alias for $2;
	p_pa_conninfo		alias for $3;
	p_pa_connretry		alias for $4;
	v_dummy			int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υå
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check if the path already exists-->ϩ¸ߤ뤫
	-- ----
	select 1 into v_dummy
			from sl_path
			where pa_server = p_pa_server
			and pa_client = p_pa_client
			for update;
	if found then
		-- ----
		-- <!--Path exists, update pa_conninfo-->ϩ¸ߡ pa_conninfo 򹹿
		-- ----
		update sl_path
				set pa_conninfo = p_pa_conninfo,
					pa_connretry = p_pa_connretry
				where pa_server = p_pa_server
				and pa_client = p_pa_client;
	else
		-- ----
		-- <!--New path-->ϩ
		--
		-- <!--In case we receive STORE_PATH events before we know-->˴ϢΡɤդΤ STORE_PATH ݤ
		-- <!--about the nodes involved in this, we generate those nodes-->硢ΥΡɤ̤ʤΤȤ
		-- <!--as pending.-->ޤ
		-- ----
		if not exists (select 1 from sl_node
						where no_id = p_pa_server) then
			perform storeNode_int (p_pa_server, &#39;&lt;event pending&gt;&#39;, &#39;f&#39;);
		end if;
		if not exists (select 1 from sl_node
						where no_id = p_pa_client) then
			perform storeNode_int (p_pa_client, &#39;&lt;event pending&gt;&#39;, &#39;f&#39;);
		end if;
		insert into sl_path
				(pa_server, pa_client, pa_conninfo, pa_connretry) values
				(p_pa_server, p_pa_client, p_pa_conninfo, p_pa_connretry);
	end if;

	-- <!--Rewrite sl_listen table-->sl_listen ơ֥ν񤭴
	perform RebuildListenEntries();

	return 0;
end;
</programlisting>
      </para>
    </section>

<!-- Function storeset( integer, text ) -->
    <section id="function.storeset-integer-text"
             xreflabel="schemadocstoreset( integer, text )">
      <title id="function.storeset-integer-text-title">
       storeset( integer, text )
      </title>
      <titleabbrev id="function.storeset-integer-text-titleabbrev">
       storeset( integer, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Generate STORE_SET event for set set_id with human readable comment set_comment-->
ͤɤǤ륳 set_comment դƤ륻å set_id Ф STORE_SET ݤޤ
        <programlisting>
declare
	p_set_id			alias for $1;
	p_set_comment			alias for $2;
	v_local_node_id			int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υå
	-- ----
	lock table sl_config_lock;

	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);

	insert into sl_set
			(set_id, set_origin, set_comment) values
			(p_set_id, v_local_node_id, p_set_comment);

	return createEvent(&#39;_schemadoc&#39;, &#39;STORE_SET&#39;, 
			p_set_id, v_local_node_id, p_set_comment);
end;
</programlisting>
      </para>
    </section>

<!-- Function storeset_int( integer, integer, text ) -->
    <section id="function.storeset-int-integer-integer-text"
             xreflabel="schemadocstoreset_int( integer, integer, text )">
      <title id="function.storeset-int-integer-integer-text-title">
       storeset_int( integer, integer, text )
      </title>
      <titleabbrev id="function.storeset-int-integer-integer-text-titleabbrev">
       storeset_int( integer, integer, text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       storeSet_int (set_id, set_origin, set_comment)

<!--Process the STORE_SET event, indicating the new set with given ID,
origin node, and human readable comment.-->
Ϳ줿̻ҡꥸΡɡӿͤɤ륳դοåȤ򼨤 STORE_SET ݤޤ
        <programlisting>
declare
	p_set_id			alias for $1;
	p_set_origin			alias for $2;
	p_set_comment			alias for $3;
	v_dummy				int4;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υå
	-- ----
	lock table sl_config_lock;

	select 1 into v_dummy
			from sl_set
			where set_id = p_set_id
			for update;
	if found then 
		update sl_set
				set set_comment = p_set_comment
				where set_id = p_set_id;
	else
		if not exists (select 1 from sl_node
						where no_id = p_set_origin) then
			perform storeNode_int (p_set_origin, &#39;&lt;event pending&gt;&#39;, &#39;f&#39;);
		end if;
		insert into sl_set
				(set_id, set_origin, set_comment) values
				(p_set_id, p_set_origin, p_set_comment);
	end if;

	return p_set_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function storetrigger( integer, name ) -->
    <section id="function.storetrigger-integer-name"
             xreflabel="schemadocstoretrigger( integer, name )">
      <title id="function.storetrigger-integer-name-title">
       storetrigger( integer, name )
      </title>
      <titleabbrev id="function.storetrigger-integer-name-titleabbrev">
       storetrigger( integer, name )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       storeTrigger (trig_tabid, trig_tgname)

<!--Submits STORE_TRIGGER event to indicate that trigger trig_tgname on
replicated table trig_tabid will NOT be disabled.-->
ʣ줿ơ֥ trig_tabid Υȥꥬ trig_tgname ̵ˤʤȤ򼨤 STORE_TRIGGER ݤȯԤޤ

        <programlisting>
declare
	p_trig_tabid		alias for $1;
	p_trig_tgname		alias for $2;
begin
	perform storeTrigger_int(p_trig_tabid, p_trig_tgname);
	return  createEvent(&#39;_schemadoc&#39;, &#39;STORE_TRIGGER&#39;,
			p_trig_tabid, p_trig_tgname);
end;
</programlisting>
      </para>
    </section>

<!-- Function storetrigger_int( integer, name ) -->
    <section id="function.storetrigger-int-integer-name"
             xreflabel="schemadocstoretrigger_int( integer, name )">
      <title id="function.storetrigger-int-integer-name-title">
       storetrigger_int( integer, name )
      </title>
      <titleabbrev id="function.storetrigger-int-integer-name-titleabbrev">
       storetrigger_int( integer, name )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       storeTrigger_int (trig_tabid, trig_tgname)

<!--Processes STORE_TRIGGER event to make sure that trigger trig_tgname on
replicated table trig_tabid is NOT disabled.-->
ʣ줿ơ֥ trig_tabid Υȥꥬ trig_tgname ̵ˤʤ褦 STORE_TRIGGER ݤޤ



        <programlisting>
declare
	p_trig_tabid		alias for $1;
	p_trig_tgname		alias for $2;
	v_tab_altered		boolean;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υå
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Get the current table status (altered or not)-->ߤΥơ֥ξ֡ѹ줿줤ʤˤγ
	-- ----
	select tab_altered into v_tab_altered
			from sl_table where tab_id = p_trig_tabid;
	if not found then
		-- ----
		-- <!--Not found is no hard error here, because that might-->Ĥʤȸ顼ϤǤϸޤ
		-- <!--mean that we are not subscribed to that set-->Τʤ顢ΥåȤɤƤޤ
		-- ----
		return 0;
	end if;

	-- ----
	-- <!--If the table is modified for replication, restore the original state-->ʣФƥơ֥뤬ѹƤСξ֤ꥹȥޤ
	-- ----
	if v_tab_altered then
		perform alterTableRestore(p_trig_tabid);
	end if;

	-- ----
	-- <!--Make sure that an entry for this trigger exists-->ΥȥꥬФ륨ȥ¸ߤγξ
	-- ----
	delete from sl_trigger
			where trig_tabid = p_trig_tabid
			  and trig_tgname = p_trig_tgname;
	insert into sl_trigger (
				trig_tabid, trig_tgname
			) values (
				p_trig_tabid, p_trig_tgname
			);

	-- ----
	-- <!--Put the table back into replicated state if it was-->⤷äʤơ֥ʣ줿֤᤹
	-- ----
	if v_tab_altered then
		perform alterTableForReplication(p_trig_tabid);
	end if;

	return p_trig_tabid;
end;
</programlisting>
      </para>
    </section>

<!-- Function subscribeset( integer, integer, integer, boolean ) -->
    <section id="function.subscribeset-integer-integer-integer-boolean"
             xreflabel="schemadocsubscribeset( integer, integer, integer, boolean )">
      <title id="function.subscribeset-integer-integer-integer-boolean-title">
       subscribeset( integer, integer, integer, boolean )
      </title>
      <titleabbrev id="function.subscribeset-integer-integer-integer-boolean-titleabbrev">
       subscribeset( integer, integer, integer, boolean )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       subscribeSet (sub_set, sub_provider, sub_receiver, sub_forward)

<!--Makes sure that the receiver is not the provider, then stores the
subscription, and publishes the SUBSCRIBE_SET event to other nodes.-->
쥷ФץХǤʤǧɤǼ¾ΥΡɤФ SUBSCRIBE_SET ݤȯԤޤ
        <programlisting>
declare
	p_sub_set			alias for $1;
	p_sub_provider			alias for $2;
	p_sub_receiver			alias for $3;
	p_sub_forward			alias for $4;
	v_set_origin			int4;
	v_ev_seqno			int8;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υåμ
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that this is called on the receiver node-->쥷ХΡɤǤ줬ƤФ뤫θ
	-- ----
	if p_sub_provider != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: subscribeSet() must be called on provider&#39;;
	end if;

	-- ----
	-- <!--Check that the origin and provider of the set are remote-->åȤΥꥸȥץХ֤򸡺
	-- ----
	select set_origin into v_set_origin
			from sl_set
			where set_id = p_sub_set;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_sub_set;
	end if;
	if v_set_origin = p_sub_receiver then
		raise exception 
				&#39;Slony-I: set origin and receiver cannot be identical&#39;;
	end if;
	if p_sub_receiver = p_sub_provider then
		raise exception 
				&#39;Slony-I: set provider and receiver cannot be identical&#39;;
	end if;


	-- ---
	-- <!--Check to see if the set contains any tables - gripe if not - bug #1226-->åȤ餫Υơ֥ͭƤ뤫  Ǥʤª  Х  #1226
	-- ---
	if not exists (select true 
		from sl_table
		where tab_set = p_sub_set) then
		raise notice &#39;subscribeSet:: set % has no tables - risk of problems - see bug 1226&#39;, p_sub_set;
		raise notice &#39;http://gborg.postgresql.org/project/slony1/bugs/bugupdate.php?1226&#39;;
	end if;

	-- ----
	-- <!--Create the SUBSCRIBE_SET event-->SUBSCRIBE_SET ݤκ
	-- ----
	v_ev_seqno :=  createEvent(&#39;_schemadoc&#39;, &#39;SUBSCRIBE_SET&#39;, 
			p_sub_set, p_sub_provider, p_sub_receiver, 
			case p_sub_forward when true then &#39;t&#39; else &#39;f&#39; end);

	-- ----
	-- <!--Call the internal procedure to store the subscription-->ɤǼ뤿ץƤӽФ
	-- ----
	perform subscribeSet_int(p_sub_set, p_sub_provider,
			p_sub_receiver, p_sub_forward);

	-- ----
	-- <!--Submit listen management events-->ƻݤȯ
	-- ----
	perform RebuildListenEntries();

	return v_ev_seqno;
end;
</programlisting>
      </para>
    </section>

<!-- Function subscribeset_int( integer, integer, integer, boolean ) -->
    <section id="function.subscribeset-int-integer-integer-integer-boolean"
             xreflabel="schemadocsubscribeset_int( integer, integer, integer, boolean )">
      <title id="function.subscribeset-int-integer-integer-integer-boolean-title">
       subscribeset_int( integer, integer, integer, boolean )
      </title>
      <titleabbrev id="function.subscribeset-int-integer-integer-integer-boolean-titleabbrev">
       subscribeset_int( integer, integer, integer, boolean )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title>Function Properties</title>
        <?dbhtml list-presentation="list"?>
        <segtitle>Language</segtitle>
        <segtitle>Return Type</segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       subscribeSet_int (sub_set, sub_provider, sub_receiver, sub_forward)

<!--Internal actions for subscribing receiver sub_receiver to subscription
set sub_set.-->
ɥå sub_set ˥쥷 sub_receiver ɤ뤿ư
        <programlisting>
declare
	p_sub_set			alias for $1;
	p_sub_provider			alias for $2;
	p_sub_receiver			alias for $3;
	p_sub_forward			alias for $4;
	v_set_origin			int4;
	v_sub_row			record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υå
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Provider change is only allowed for active sets-->ΥåȤФƤΤߥץХѹǽ
	-- ----
	if p_sub_receiver = getLocalNodeId(&#39;_schemadoc&#39;) then
		select sub_active into v_sub_row from sl_subscribe
				where sub_set = p_sub_set
				and sub_receiver = p_sub_receiver;
		if found then
			if not v_sub_row.sub_active then
				raise exception &#39;Slony-I: set % is not active, cannot change provider&#39;,
						p_sub_set;
			end if;
		end if;
	end if;

	-- ----
	-- <!--Try to change provider and/or forward for an existing subscription-->ץХѹλߡ/⤷ϡ¸ιɤФȯ
	-- ----
	update sl_subscribe
			set sub_provider = p_sub_provider,
				sub_forward = p_sub_forward
			where sub_set = p_sub_set
			and sub_receiver = p_sub_receiver;
	if found then
		return p_sub_set;
	end if;

	-- ----
	-- <!--Not found, insert a new one-->Ĥʤ翷Τ
	-- ----
	if not exists (select true from sl_path
			where pa_server = p_sub_provider
			and pa_client = p_sub_receiver)
	then
		insert into sl_path
				(pa_server, pa_client, pa_conninfo, pa_connretry)
				values 
				(p_sub_provider, p_sub_receiver, 
				&#39;&lt;event pending&gt;&#39;, 10);
	end if;
	insert into sl_subscribe
			(sub_set, sub_provider, sub_receiver, sub_forward, sub_active)
			values (p_sub_set, p_sub_provider, p_sub_receiver,
				p_sub_forward, false);

	-- ----
	-- <!--If the set origin is here, then enable the subscription-->åȥꥸ󤬤ˤСɤͭ
	-- ----
	select set_origin into v_set_origin
			from sl_set
			where set_id = p_sub_set;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_sub_set;
	end if;

	if v_set_origin = getLocalNodeId(&#39;_schemadoc&#39;) then
		perform createEvent(&#39;_schemadoc&#39;, &#39;ENABLE_SUBSCRIPTION&#39;, 
				p_sub_set, p_sub_provider, p_sub_receiver, 
				case p_sub_forward when true then &#39;t&#39; else &#39;f&#39; end);
		perform enableSubscription(p_sub_set, 
				p_sub_provider, p_sub_receiver);
	end if;

	-- <!--Rewrite sl_listen table-->sl_listen ơ֥ν񤭴
	perform RebuildListenEntries();

	return p_sub_set;
end;
</programlisting>
      </para>
    </section>

<!-- Function tableaddkey( text ) -->
    <section id="function.tableaddkey-text"
             xreflabel="schemadoctableaddkey( text )">
      <title id="function.tableaddkey-text-title">
       tableaddkey( text )
      </title>
      <titleabbrev id="function.tableaddkey-text-titleabbrev">
       tableaddkey( text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
       tableAddKey (tab_fqname) - <!--if the table has not got a column of the
form _Slony-I_&lt;clustername&gt;_rowID, then add it as a bigint, defaulted
to nextval() for a sequence created for the cluster.-->
⤷ơ֥뤬ե _Slony-I_&lt;clustername&gt;_rowID ̤ǤСbigint ɲäΥ饹Ф줿󥹤Ф nextval() ǥեȤȤޤ
        <programlisting>
declare
	p_tab_fqname            alias for $1;
	v_tab_fqname_quoted	text default &#39;&#39;;
	v_attkind		text default &#39;&#39;;
	v_attrow		record;
	v_have_serial		bool default &#39;f&#39;;
begin
	v_tab_fqname_quoted := slon_quote_input(p_tab_fqname);
	--
	-- <!--Loop over the attributes of this relation-->Υ졼°롼פƤΥ桼
	-- <!--and add a &quot;v&quot; for every user column, and a &quot;k&quot;-->&quot;v&quot; ɲä⤷ Slony-I ̤򸫽Ф
	-- <!--if we find the Slony-I special serial column.-->&quot;k&quot; ɲäޤ
	--
	for v_attrow in select PGA.attnum, PGA.attname
			from &quot;pg_catalog&quot;.pg_class PGC,
			    &quot;pg_catalog&quot;.pg_namespace PGN,
				&quot;pg_catalog&quot;.pg_attribute PGA
			where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
			    slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGN.oid = PGC.relnamespace
				and PGA.attrelid = PGC.oid
				and not PGA.attisdropped
				and PGA.attnum &gt; 0
			order by attnum
	loop
		if v_attrow.attname = &#39;_Slony-I_schemadoc_rowID&#39; then
		    v_attkind := v_attkind || &#39;k&#39;;
			v_have_serial := &#39;t&#39;;
		else
			v_attkind := v_attkind || &#39;v&#39;;
		end if;
	end loop;
	
	--
	-- <!--A table must have at least one attribute, so not finding-->ơ֥ϾʤȤ 1 Ĥ°ͭʤФʤ餺
	-- <!--anything means the table does not exist.-->⸫Ĥʤϥơ֥뤬¸ߤʤ̣ޤ
	--
	if not found then
		raise exception &#39;Slony-I: table % not found&#39;, v_tab_fqname_quoted;
	end if;

	--
	-- <!--If it does not have the special serial column, we-->⤷̤Υꥢͭʤ硢ɲäʤФʤޤ
	-- <!--have to add it. This will be only half way done.-->ǤȾʬβλ˲᤮ޤ
	-- <!--The function to add the table to the set must finish-->Ƥδ¸ιԤ򹹿 NOT NULL  UNIQUE ȼä
	-- <!--these definitions with NOT NULL and UNIQUE after-->ơ֥򥻥åȤɲäؿϴλʤ
	-- <!--updating all existing rows.-->ʤޤ
	--
	if not v_have_serial then
		execute &#39;lock table &#39; || v_tab_fqname_quoted ||
			&#39; in access exclusive mode&#39;;
		execute &#39;alter table only &#39; || v_tab_fqname_quoted ||
			&#39; add column &quot;_Slony-I_schemadoc_rowID&quot; bigint;&#39;;
		execute &#39;alter table only &#39; || v_tab_fqname_quoted ||
			&#39; alter column &quot;_Slony-I_schemadoc_rowID&quot; &#39; ||
			&#39; set default &quot;pg_catalog&quot;.nextval(&#39;&#39;sl_rowid_seq&#39;&#39;);&#39;;

		v_attkind := v_attkind || &#39;k&#39;;
	end if;

	--
	-- <!--Return the resulting Slony-I attkind-->̤ Slony-I attkind ᤷޤ
	--
	return v_attkind;
end;
</programlisting>
      </para>
    </section>

<!-- Function tabledropkey( integer ) -->
    <section id="function.tabledropkey-integer"
             xreflabel="schemadoctabledropkey( integer )">
      <title id="function.tabledropkey-integer-title">
       tabledropkey( integer )
      </title>
      <titleabbrev id="function.tabledropkey-integer-titleabbrev">
       tabledropkey( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       tableDropKey (tab_id)

<!--If the specified table has a column &quot;_Slony-I_&lt;clustername&gt;_rowID&quot;,
then drop it.-->
⤷ꤵ줿ơ֥ &quot;_Slony-I_&lt;clustername&gt;_rowID&quot; ¸ߤкޤ
        <programlisting>
declare
	p_tab_id		alias for $1;
	v_tab_fqname		text;
	v_tab_oid		oid;
begin
	-- ----
	-- <!--Grab the central configuration lock-->Υå
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Construct the tables fully qualified name and get its oid-->ơ֥δ̾Fully Qualified NameˤۤΥ֥ȼ̻ҡoidˤޤ
	-- ----
	select slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
				slon_quote_brute(PGC.relname),
				PGC.oid into v_tab_fqname, v_tab_oid
			from sl_table T,
				&quot;pg_catalog&quot;.pg_class PGC,
				&quot;pg_catalog&quot;.pg_namespace PGN
			where T.tab_id = p_tab_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid;
	if not found then
		raise exception &#39;Slony-I: table with ID % not found&#39;, p_tab_id;
	end if;

	-- ----
	-- <!--Drop the special serial ID column if the table has it-->⤷ơ֥̤ʥꥢ뼱̻¸ߤкޤ
	-- ----
	if exists (select true from &quot;pg_catalog&quot;.pg_attribute
			where attrelid = v_tab_oid
				and attname = &#39;_Slony-I_schemadoc_rowID&#39;)
	then
		execute &#39;lock table &#39; || v_tab_fqname ||
				&#39; in access exclusive mode&#39;;
		execute &#39;alter table &#39; || v_tab_fqname ||
				&#39; drop column &quot;_Slony-I_schemadoc_rowID&quot;&#39;;
	end if;

	return p_tab_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function tablehasserialkey( text ) -->
    <section id="function.tablehasserialkey-text"
             xreflabel="schemadoctablehasserialkey( text )">
      <title id="function.tablehasserialkey-text-title">
       tablehasserialkey( text )
      </title>
      <titleabbrev id="function.tablehasserialkey-text-titleabbrev">
       tablehasserialkey( text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>boolean</seg>
        </seglistitem>
       </segmentedlist>
 
       tableHasSerialKey (tab_fqname)

<!--Checks if a table has our special serial key column that is used if
the table has no natural unique constraint.-->
ơ֥뤬̤ΰʤ˻Ѥ롢̤Υꥢ륭ͭƤ뤫ޤ

        <programlisting>
declare
	p_tab_fqname            alias for $1;
	v_tab_fqname_quoted	text default &#39;&#39;;
	v_attnum		int2;
begin
	v_tab_fqname_quoted := slon_quote_input(p_tab_fqname);
	select PGA.attnum into v_attnum
			from &quot;pg_catalog&quot;.pg_class PGC,
				&quot;pg_catalog&quot;.pg_namespace PGN,
				&quot;pg_catalog&quot;.pg_attribute PGA
			where slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
				slon_quote_brute(PGC.relname) = v_tab_fqname_quoted
				and PGC.relnamespace = PGN.oid
				and PGA.attrelid = PGC.oid
				and PGA.attname = &#39;_Slony-I_schemadoc_rowID&#39;
				and not PGA.attisdropped;
	return found;
end;
</programlisting>
      </para>
    </section>

<!-- Function terminatenodeconnections( name ) -->
    <section id="function.terminatenodeconnections-name"
             xreflabel="schemadocterminatenodeconnections( name )">
      <title id="function.terminatenodeconnections-name-title">
       terminatenodeconnections( name )
      </title>
      <titleabbrev id="function.terminatenodeconnections-name-titleabbrev">
       terminatenodeconnections( name )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>C</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--terminates connections to the node and terminates the process-->
ΥΡɤؤ³λץ򽪤ޤ
        <programlisting>_Slony_I_terminateNodeConnections</programlisting>
      </para>
    </section>

<!-- Function uninstallnode(  ) -->
    <section id="function.uninstallnode"
             xreflabel="schemadocuninstallnode(  )">
      <title id="function.uninstallnode-title">
       uninstallnode(  )
      </title>
      <titleabbrev id="function.uninstallnode-titleabbrev">
       uninstallnode(  )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Reset the whole database to standalone by removing the whole replication system.-->
ƤʣƥƤΥǡ١򥹥ɥ˺ꤷޤ
        <programlisting>
declare
	v_tab_row		record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--This is us ... time for suicide! Restore all tables to-->ϻ䤿  Ǥνִ֡ƤΥơ֥
	-- <!--their original status.-->ξ֤˥ꥹȥ
	-- ----
	for v_tab_row in select * from sl_table loop
		perform alterTableRestore(v_tab_row.tab_id);
		perform tableDropKey(v_tab_row.tab_id);
	end loop;

	raise notice &#39;Slony-I: Please drop schema &quot;_schemadoc&quot;&#39;;
	return 0;
end;
</programlisting>
      </para>
    </section>

<!-- Function unlockset( integer ) -->
    <section id="function.unlockset-integer"
             xreflabel="schemadocunlockset( integer )">
      <title id="function.unlockset-integer-title">
       unlockset( integer )
      </title>
      <titleabbrev id="function.unlockset-integer-titleabbrev">
       unlockset( integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Remove the special trigger from all tables of a set that disables access to it.-->
˥ǽˤ륻åȤƤΥơ֥뤫̤ʥȥꥬޤ
        <programlisting>
declare
	p_set_id			alias for $1;
	v_local_node_id			int4;
	v_set_row			record;
	v_tab_row			record;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that the set exists and that we are the origin-->åȤ¸ߤ䤿ꥸ
	-- <!--and that it is not already locked.-->̤åƤʤθ
	-- ----
	v_local_node_id := getLocalNodeId(&#39;_schemadoc&#39;);
	select * into v_set_row from sl_set
			where set_id = p_set_id
			for update;
	if not found then
		raise exception &#39;Slony-I: set % not found&#39;, p_set_id;
	end if;
	if v_set_row.set_origin &lt;&gt; v_local_node_id then
		raise exception &#39;Slony-I: set % does not originate on local node&#39;,
				p_set_id;
	end if;
	if v_set_row.set_locked isnull then
		raise exception &#39;Slony-I: set % is not locked&#39;, p_set_id;
	end if;

	-- ----
	-- <!--Drop the lockedSet trigger from all tables in the set.-->åƤΥơ֥뤫 lockedSet ȥꥬ
	-- ----
	for v_tab_row in select T.tab_id,
			slon_quote_brute(PGN.nspname) || &#39;.&#39; ||
			slon_quote_brute(PGC.relname) as tab_fqname
			from sl_table T,
				&quot;pg_catalog&quot;.pg_class PGC, &quot;pg_catalog&quot;.pg_namespace PGN
			where T.tab_set = p_set_id
				and T.tab_reloid = PGC.oid
				and PGC.relnamespace = PGN.oid
			order by tab_id
	loop
		execute &#39;drop trigger &quot;_schemadoc_lockedset_&#39; || 
				v_tab_row.tab_id || &#39;&quot; on &#39; || v_tab_row.tab_fqname;
	end loop;

	-- ----
	-- <!--Clear out the set_locked field-->set_locked եɤݽ
	-- ----
	update sl_set
			set set_locked = NULL
			where set_id = p_set_id;

	return p_set_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function unsubscribeset( integer, integer ) -->
    <section id="function.unsubscribeset-integer-integer"
             xreflabel="schemadocunsubscribeset( integer, integer )">
      <title id="function.unsubscribeset-integer-integer-title">
       unsubscribeset( integer, integer )
      </title>
      <titleabbrev id="function.unsubscribeset-integer-integer-titleabbrev">
       unsubscribeset( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>bigint</seg>
        </seglistitem>
       </segmentedlist>
 
       unsubscribeSet (sub_set, sub_receiver) 

<!--Unsubscribe node sub_receiver from subscription set sub_set.  This is
invoked on the receiver node.  It verifies that this does not break
any chains (e.g. - where sub_receiver is a provider for another node),
then restores tables, drops Slony-specific keys, drops table entries
for the set, drops the subscription, and generates an UNSUBSCRIBE_SET
node to publish that the node is being dropped.-->
ɥå set sub_set Ρ sub_receiver ɤˤޤϥ쥷ХΡɤǵưޤ줬ǡʤѹˤȿʤȼ¾ڤС㤨С¾ΥΡɤФ sub_receiver ץХǤ뤳ȡˡSlony ͭΥΥåȤФơ֥륨ȥɤƤΥΡɤ줿ȯԤ UNSUBSCRIBE_SET ݤޤ

        <programlisting>
declare
	p_sub_set			alias for $1;
	p_sub_receiver			alias for $2;
	v_tab_row			record;
begin
	-- ----
	-- Grab the central configuration lock
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--Check that this is called on the receiver node-->쥷ХΡɤǤ줬ƤФθ
	-- ----
	if p_sub_receiver != getLocalNodeId(&#39;_schemadoc&#39;) then
		raise exception &#39;Slony-I: unsubscribeSet() must be called on receiver&#39;;
	end if;

	-- ----
	-- <!--Check that this does not break any chains-->줬ǡʤϢˤȿʤθ
	-- ----
	if exists (select true from sl_subscribe
			where sub_set = p_sub_set
				and sub_provider = p_sub_receiver)
	then
		raise exception &#39;Slony-I: Cannot unsubscibe set % while being provider&#39;,
				p_sub_set;
	end if;

	-- ----
	-- <!--Restore all tables original triggers and rules and remove-->ƤΥơ֥θΥȥꥬȥ롼ꥹȥ
	-- <!--our replication stuff.-->ʣν
	-- ----
	for v_tab_row in select tab_id from sl_table
			where tab_set = p_sub_set
			order by tab_id
	loop
		perform alterTableRestore(v_tab_row.tab_id);
		perform tableDropKey(v_tab_row.tab_id);
	end loop;

	-- ----
	-- <!--Remove the setsync status. This will also cause the-->setsync ơκƱ
	-- <!--worker thread to ignore the set and stop replicating-->ȼԥåɡworker threadˤåȤ̵뤷ʣ򤹤
	-- <!--right now.-->ߤˤʤޤ
	-- ----
	delete from sl_setsync
			where ssy_setid = p_sub_set;

	-- ----
	-- <!--Remove all sl_table and sl_sequence entries for this set.-->ΥåȤФƤ sl_table  sl_sequence Υȥ
	-- <!--Should we ever subscribe again, the initial data-->ٹɤ򳫻ϤȤСǡʣ̲
	-- <!--copy process will create new ones.-->˺ޤ
	-- ----
	delete from sl_table
			where tab_set = p_sub_set;
	delete from sl_sequence
			where seq_set = p_sub_set;

	-- ----
	-- <!--Call the internal procedure to drop the subscription-->ɺΤץθƤӽФ
	-- ----
	perform unsubscribeSet_int(p_sub_set, p_sub_receiver);

	-- Rewrite sl_listen table
	perform RebuildListenEntries();

	-- ----
	-- <!--Create the UNSUBSCRIBE_SET event--> UNSUBSCRIBE_SET ݤκ
	-- ----
	return  createEvent(&#39;_schemadoc&#39;, &#39;UNSUBSCRIBE_SET&#39;, 
			p_sub_set, p_sub_receiver);
end;
</programlisting>
      </para>
    </section>

<!-- Function unsubscribeset_int( integer, integer ) -->
    <section id="function.unsubscribeset-int-integer-integer"
             xreflabel="schemadocunsubscribeset_int( integer, integer )">
      <title id="function.unsubscribeset-int-integer-integer-title">
       unsubscribeset_int( integer, integer )
      </title>
      <titleabbrev id="function.unsubscribeset-int-integer-integer-titleabbrev">
       unsubscribeset_int( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       unsubscribeSet_int (sub_set, sub_receiver)

<!--All the REAL work of removing the subscriber is done before the event
is generated, so this function just has to drop the references to the
subscription in sl_subscribe.-->
ݤ˹ɥΡɤƤμºȤλޤδؿ sl_subscribe ǤιɤФ뻲ȤΤߤ˻ߤޤޤ
        <programlisting>
declare
	p_sub_set			alias for $1;
	p_sub_receiver			alias for $2;
begin
	-- ----
	-- <!--Grab the central configuration lock-->˥å
	-- ----
	lock table sl_config_lock;

	-- ----
	-- <!--All the real work is done before event generation on the-->ɥΡɾǻݤ
	-- <!--subscriber.-->ƤμºȤλ
	-- ----
	delete from sl_subscribe
			where sub_set = p_sub_set
				and sub_receiver = p_sub_receiver;

	-- Rewrite sl_listen table
	perform RebuildListenEntries();

	return p_sub_set;
end;
</programlisting>
      </para>
    </section>

<!-- Function updaterelname( integer, integer ) -->
    <section id="function.updaterelname-integer-integer"
             xreflabel="schemadocupdaterelname( integer, integer )">
      <title id="function.updaterelname-integer-integer-title">
       updaterelname( integer, integer )
      </title>
      <titleabbrev id="function.updaterelname-integer-integer-titleabbrev">
       updaterelname( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       updateRelname(set_id, only_on_node)
        <programlisting>
declare
        p_set_id                alias for $1;
        p_only_on_node          alias for $2;
        v_no_id                 int4;
        v_set_origin            int4;
begin
        -- ----
        -- <!--Grab the central configuration lock-->Υå
        -- ----
        lock table sl_config_lock;

        -- ----
        -- <!--Check that we either are the set origin or a current-->䤿åȥꥸ⤷ϥåȤθߤιɥΡ
        -- <!--subscriber of the set.-->Ǥ뤫γǧ
        -- ----
        v_no_id := getLocalNodeId(&#39;_schemadoc&#39;);
        select set_origin into v_set_origin
                        from sl_set
                        where set_id = p_set_id
                        for update;
        if not found then
                raise exception &#39;Slony-I: set % not found&#39;, p_set_id;
        end if;
        if v_set_origin &lt;&gt; v_no_id
                and not exists (select 1 from sl_subscribe
                        where sub_set = p_set_id
                        and sub_receiver = v_no_id)
        then
                return 0;
        end if;
    
        -- ----
        -- <!--If execution on only one node is requested, check that-->ä 1 ĤΥΡɾǤμ¹Ԥ׵ᤵ
        -- <!--we are that node.-->䤿ΥΡɤǤ뤫򸡺
        -- ----
        if p_only_on_node &gt; 0 and p_only_on_node &lt;&gt; v_no_id then
                return 0;
        end if;
        update sl_table set 
                tab_relname = PGC.relname, tab_nspname = PGN.nspname
                from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN 
                where sl_table.tab_reloid = PGC.oid
                        and PGC.relnamespace = PGN.oid;
        update sl_sequence set
                seq_relname = PGC.relname, seq_nspname = PGN.nspname
                from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
                where sl_sequence.seq_reloid = PGC.oid
                and PGC.relnamespace = PGN.oid;
        return p_set_id;
end;
</programlisting>
      </para>
    </section>

<!-- Function updatereloid( integer, integer ) -->
    <section id="function.updatereloid-integer-integer"
             xreflabel="schemadocupdatereloid( integer, integer )">
      <title id="function.updatereloid-integer-integer-title">
       updatereloid( integer, integer )
      </title>
      <titleabbrev id="function.updatereloid-integer-integer-titleabbrev">
       updatereloid( integer, integer )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>integer</seg>
        </seglistitem>
       </segmentedlist>
 
       updateReloid(set_id, only_on_node)

<!--Updates the respective reloids in sl_table and sl_seqeunce based on
their respective FQN-->
줾δ̾FQNˤ˴Ť sl_table  sl_seqeunce ˤ뤽줾Υơ֥뼱̻ҡreloidˤ򹹿ޤ
        <programlisting>
declare
        p_set_id                alias for $1;
        p_only_on_node          alias for $2;
        v_no_id                 int4;
        v_set_origin            int4;
begin
        -- ----
        -- <!--Grab the central configuration lock-->Υå
        -- ----
        lock table sl_config_lock;

        -- ----
        -- <!--Check that we either are the set origin or a current-->䤿åȥꥸ󤫡⤷ϸߤΥåȤ
        -- <!--subscriber of the set.-->ɥΡɤθ
        -- ----
        v_no_id := getLocalNodeId(&#39;_schemadoc&#39;);
        select set_origin into v_set_origin
                        from sl_set
                        where set_id = p_set_id
                        for update;
        if not found then
                raise exception &#39;Slony-I: set % not found&#39;, p_set_id;
        end if;
        if v_set_origin &lt;&gt; v_no_id
                and not exists (select 1 from sl_subscribe
                        where sub_set = p_set_id
                        and sub_receiver = v_no_id)
        then
                return 0;
        end if;

        -- ----
        -- <!--If execution on only one node is requested, check that-->ä 1 ĤΥΡɾǤμ¹Ԥ׵ᤵ
        -- <!--we are that node.-->䤿ΥΡɤǤ뤫򸡺
        -- ----
        if p_only_on_node &gt; 0 and p_only_on_node &lt;&gt; v_no_id then
                return 0;
        end if;
        update sl_table set
                tab_reloid = PGC.oid
                from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
                where slon_quote_brute(sl_table.tab_relname) = slon_quote_brute(PGC.relname)
                        and PGC.relnamespace = PGN.oid
			and slon_quote_brute(PGN.nspname) = slon_quote_brute(sl_table.tab_nspname);

        update sl_sequence set
                seq_reloid = PGC.oid
                from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
                where slon_quote_brute(sl_sequence.seq_relname) = slon_quote_brute(PGC.relname)
                	and PGC.relnamespace = PGN.oid
			and slon_quote_brute(PGN.nspname) = slon_quote_brute(sl_sequence.seq_nspname);

        return  createEvent(&#39;_schemadoc&#39;, &#39;RESET_CONFIG&#39;,
                        p_set_id, p_only_on_node);
end;
</programlisting>
      </para>
    </section>

<!-- Function upgradeschema( text ) -->
    <section id="function.upgradeschema-text"
             xreflabel="schemadocupgradeschema( text )">
      <title id="function.upgradeschema-text-title">
       upgradeschema( text )
      </title>
      <titleabbrev id="function.upgradeschema-text-titleabbrev">
       upgradeschema( text )
      </titleabbrev>

      <para>
       <segmentedlist>
        <title><!--Function Properties-->ؿ</title>
        <?dbhtml list-presentation="list"?>
        <segtitle><!--Language--></segtitle>
        <segtitle><!--Return Type--></segtitle>
        <seglistitem>
         <seg>PLPGSQL</seg>
         <seg>text</seg>
        </seglistitem>
       </segmentedlist>
 
       <!--Called during &quot;update functions&quot; by slonik to perform schema changes-->
ѹ¹Ԥ뤿 slonik ˤ &quot;update functions&quot; ǸƤӽФޤ
        <programlisting>

declare
        p_old   alias for $1;
begin
	-- <!--upgrade -->sl_table ι
	if p_old = &#39;1.0.2&#39; or p_old = &#39;1.0.5&#39; then
		-- Add new column(s) sl_table.tab_relname, sl_table.tab_nspname
		execute &#39;alter table sl_table add column tab_relname name&#39;;
		execute &#39;alter table sl_table add column tab_nspname name&#39;;

		-- <!--populate the colums with data-->ǡ populate ޤ
		update sl_table set
			tab_relname = PGC.relname, tab_nspname = PGN.nspname
			from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
			where sl_table.tab_reloid = PGC.oid
			and PGC.relnamespace = PGN.oid;

		-- <!--constrain the colums-->ݤޤ
		execute &#39;alter table sl_table alter column tab_relname set NOT NULL&#39;;
		execute &#39;alter table sl_table alter column tab_nspname set NOT NULL&#39;;

	end if;

	-- <!--upgrade -->sl_sequence 򥢥åץ졼ɤޤ
	if p_old = &#39;1.0.2&#39; or p_old = &#39;1.0.5&#39; then
		-- Add new column(s) sl_sequence.seq_relname, sl_sequence.seq_nspname
		execute &#39;alter table sl_sequence add column seq_relname name&#39;;
		execute &#39;alter table sl_sequence add column seq_nspname name&#39;;

		-- <!--populate the columns with data-->ǡ populate ޤ
		update sl_sequence set
			seq_relname = PGC.relname, seq_nspname = PGN.nspname
			from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN
			where sl_sequence.seq_reloid = PGC.oid
			and PGC.relnamespace = PGN.oid;

		-- <!--constrain the data-->ǡݤޤ
		execute &#39;alter table sl_sequence alter column seq_relname set NOT NULL&#39;;
		execute &#39;alter table sl_sequence alter column seq_nspname set NOT NULL&#39;;
	end if;

	-- ----
	-- <!--Changes from 1.0.x to 1.1.0-->1.0.x  1.1.0 ؤѹ
	-- ----
	if p_old = &#39;1.0.2&#39; or p_old = &#39;1.0.5&#39; then
		-- Add new column sl_node.no_spool for virtual spool nodes
		execute &#39;alter table sl_node add column no_spool boolean&#39;;
		update sl_node set no_spool = false;
	end if;
	return p_old;
end;
</programlisting>
      </para>
    </section>

  </chapter>



