diff --git a/doc/src/sgml/pgstatstatements.sgml b/doc/src/sgml/pgstatstatements.sgml
new file mode 100644
index ca7bd44..2355f1a
*** a/doc/src/sgml/pgstatstatements.sgml
--- b/doc/src/sgml/pgstatstatements.sgml
***************
*** 24,33 ****
  
    <para>
     The statistics gathered by the module are made available via a system view
!    named <structname>pg_stat_statements</>.  This view contains one row for
!    each distinct query text, database ID, and user ID (up to the maximum
!    number of distinct statements that the module can track).  The columns
!    of the view are shown in <xref linkend="pgstatstatements-columns">.
    </para>
  
    <table id="pgstatstatements-columns">
--- 24,78 ----
  
    <para>
     The statistics gathered by the module are made available via a system view
!    named <structname>pg_stat_statements</>.  The module normalizes queries,
!    matching them based on an internal hash value.  
!    <structname>pg_stat_statements</> contains one row for each distinct
!    combination of internal query hash, database ID, and user ID (up to the
!    maximum number of distinct statements that the module can track).  The
!    columns of the view are shown in 
!    <xref linkend="pgstatstatements-columns">.
!   </para>
! 
!   <para>
!    Utility commands are all those other than <command>SELECT</>,
!    <command>INSERT</>, <command>UPDATE</> and <command>DELETE</>.  In the case
!    of utility statements, the query hash value identifier is derived from the
!    query string.  In the case of all other statements, the statement's query
!    tree is hashed to produce its query hash identifier.  The query tree is an
!    internal structure that results from the transformation process, later in the
!    parser stage, immediately prior to the rewrite stage.  Queries that are
!    deemed to be equivalent, due to not actually differing in ways that the
!    implementation deems essential to the query, have execution statistics
!    aggregated into a single entry. This is particularly useful for queries with
!    inline parameters.
!   </para>
! 
!   <para>
!    Matching queries based on their query tree hash value can produce results
!    that are not consistent with an implementation that differentiates based on
!    each query's SQL string, in non-obvious ways. For example, the current value
!    of <varname>search_path</> might affect query differentiation if a change
!    caused parse analysis to resolve different relations at different times, such
!    as relations that have identical definitions but are located in different
!    schemas. The two resulting distinct entries would have identical query
!    strings. 
!   </para>
! 
!   <para>
!    The execution costs of <command>DO INSTEAD</> and <command>DO ALSO</> rules
!    are attributed to their originating query; a separate entry will not be
!    created for the rule action. <command>DO NOTHING</> rules will naturally not
!    add an entry at all, since a query is not actually executed. 
!   </para>
! 
!   <para>
!    <filename>pg_stat_statements</filename> considers some utility commands to
!    consist of two distinct commands: The utility command proper, and a nested
!    <acronym>DML</> command.  Such utility commands include <command>DECLARE
!    CURSOR</>, <command>SELECT INTO</> and <command>EXPLAIN ANALYZE</>.
!    Therefore, to see the true execution costs of these statements, it is
!    necessary to set both pg_stat_statements.track_utility to 'on' and
!    pg_stat_statements.track to 'all'.
    </para>
  
    <table id="pgstatstatements-columns">
***************
*** 61,67 ****
        <entry><structfield>query</structfield></entry>
        <entry><type>text</type></entry>
        <entry></entry>
!       <entry>Text of the statement (up to <xref linkend="guc-track-activity-query-size"> bytes)</entry>
       </row>
  
       <row>
--- 106,112 ----
        <entry><structfield>query</structfield></entry>
        <entry><type>text</type></entry>
        <entry></entry>
!       <entry>Representative, canonicalized text of the statement (up to <xref linkend="guc-track-activity-query-size"> bytes)</entry>
       </row>
  
       <row>
***************
*** 193,206 ****
     queries executed by other users.  They can see the statistics, however,
     if the view has been installed in their database.
    </para>
  
!   <para>
!    Note that statements are considered the same if they have the same text,
!    regardless of the values of any out-of-line parameters used in the
!    statement.  Using out-of-line parameters will help to group statements
!    together and may make the statistics more useful.
!   </para>
!  </sect2>
  
   <sect2>
    <title>Functions</title>
--- 238,256 ----
     queries executed by other users.  They can see the statistics, however,
     if the view has been installed in their database.
    </para>
+   <warning>
+    <para>
+     A notable artefact of the module's query hash matching based implementation
+     is that there may be undetectable collisions. While such collisions are very
+     unlikely, the possibility cannot be absolutely precluded, and as such the
+     count values of two distinct queries may be incorrectly aggregated together
+     as a single entry within <structname>pg_stat_statements</> in isolated
+     cases. However, it is guaranteed that such collisions cannot occur between
+     entries for different databases or different users.
+    </para>
+   </warning>
  
!   </sect2>
  
   <sect2>
    <title>Functions</title>
***************
*** 254,264 ****
       <para>
        <varname>pg_stat_statements.track</varname> controls which statements
        are counted by the module.
!       Specify <literal>top</> to track top-level statements (those issued
!       directly by clients), <literal>all</> to also track nested statements
!       (such as statements invoked within functions), or <literal>none</> to
!       disable.
!       The default value is <literal>top</>.
        Only superusers can change this setting.
       </para>
      </listitem>
--- 304,314 ----
       <para>
        <varname>pg_stat_statements.track</varname> controls which statements
        are counted by the module.
! 	  Specify <literal>top</> to track top-level statements (those issued
! 	  directly by clients), <literal>all</> to also track nested statements
! 	  (such as statements invoked within functions), or <literal>none</> to
! 	  disable.
! 	  The default value is <literal>top</>.
        Only superusers can change this setting.
       </para>
      </listitem>
***************
*** 271,282 ****
  
      <listitem>
       <para>
!       <varname>pg_stat_statements.track_utility</varname> controls whether
!       utility commands are tracked by the module.  Utility commands are
!       all those other than <command>SELECT</>, <command>INSERT</>,
!       <command>UPDATE</> and <command>DELETE</>.
!       The default value is <literal>on</>.
!       Only superusers can change this setting.
       </para>
      </listitem>
     </varlistentry>
--- 321,329 ----
  
      <listitem>
       <para>
! 	  <varname>pg_stat_statements.track_utility</varname> controls whether
! 	  utility commands are tracked by the module.  The default value is
! 	  <literal>on</>.  Only superusers can change this setting.
       </para>
      </listitem>
     </varlistentry>
*************** pg_stat_statements.track = all
*** 329,348 ****
  bench=# SELECT pg_stat_statements_reset();
  
  $ pgbench -i bench
! $ pgbench -c10 -t300 -M prepared bench
  
  bench=# \x
  bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit /
                 nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
            FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
  -[ RECORD 1 ]---------------------------------------------------------------------
! query       | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2;
  calls       | 3000
  total_time  | 9.60900100000002
  rows        | 2836
  hit_percent | 99.9778970000200936
  -[ RECORD 2 ]---------------------------------------------------------------------
! query       | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2;
  calls       | 3000
  total_time  | 8.015156
  rows        | 2990
--- 376,395 ----
  bench=# SELECT pg_stat_statements_reset();
  
  $ pgbench -i bench
! $ pgbench -c10 -t300
  
  bench=# \x
  bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit /
                 nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
            FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
  -[ RECORD 1 ]---------------------------------------------------------------------
! query       | UPDATE pgbench_branches SET bbalance = bbalance + ? WHERE bid = ?;
  calls       | 3000
  total_time  | 9.60900100000002
  rows        | 2836
  hit_percent | 99.9778970000200936
  -[ RECORD 2 ]---------------------------------------------------------------------
! query       | UPDATE pgbench_tellers SET tbalance = tbalance + ? WHERE tid = ?;
  calls       | 3000
  total_time  | 8.015156
  rows        | 2990
*************** total_time  | 0.310624
*** 354,360 ****
  rows        | 100000
  hit_percent | 0.30395136778115501520
  -[ RECORD 4 ]---------------------------------------------------------------------
! query       | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2;
  calls       | 3000
  total_time  | 0.271741999999997
  rows        | 3000
--- 401,407 ----
  rows        | 100000
  hit_percent | 0.30395136778115501520
  -[ RECORD 4 ]---------------------------------------------------------------------
! query       | UPDATE pgbench_accounts SET abalance = abalance + ? WHERE aid = ?;
  calls       | 3000
  total_time  | 0.271741999999997
  rows        | 3000
