From 6e7a6e3d5c119460f60b67f996fb4183af57c4b0 Mon Sep 17 00:00:00 2001
From: Alexandre Felipe <o.alexandre.felipe@gmail.com>
Date: Thu, 16 Jul 2026 10:08:17 +0100
Subject: [PATCH-v15.1 5/6] SLOPE: documentation

---
 doc/src/sgml/btree.sgml  |  5 +-
 doc/src/sgml/config.sgml | 35 ++++++++++++++
 doc/src/sgml/xfunc.sgml  | 98 ++++++++++++++++++++++++++++++++++++++--
 3 files changed, 132 insertions(+), 6 deletions(-)

diff --git a/doc/src/sgml/btree.sgml b/doc/src/sgml/btree.sgml
index 027361f20bb..63cc68a3dcf 100644
--- a/doc/src/sgml/btree.sgml
+++ b/doc/src/sgml/btree.sgml
@@ -465,8 +465,9 @@ returns bool
       equality</quote>) support functions, registered under support
      function number 4.  These functions allow the core code to
      determine when it is safe to apply the btree deduplication
-     optimization.  Currently, <function>equalimage</function>
-     functions are only called when building or rebuilding an index.
+     optimization.  <function>equalimage</function> functions might
+     be called when building or rebuilding an index, or planning an
+     index scan.
     </para>
     <para>
      An <function>equalimage</function> function must have the
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 596fd45a3db..b2e14f16698 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -6254,6 +6254,41 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-enable-slope" xreflabel="enable_slope">
+      <term><varname>enable_slope</varname> (<type>boolean</type>)
+      <indexterm>
+       <primary><varname>enable_slope</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Enables or disables query planner's slope analysis. The slope analysis
+        gives the query executor the ability to use an index when the data
+        order is implied but not direct. Consider the following example</para>
+
+       <programlisting>
+CREATE TABLE orders(created_at timestamp, ...);
+CREATE INDEX ON orders(created_at);
+SELECT created_at::date, count(1)
+FROM orders GROUP BY 1
+ORDER BY 1
+LIMIT 5;
+       </programlisting>
+
+       <para>
+        The table has an index on <varname>created_at</varname> of
+        type <type>timestamp</type>. Grouping takes advantage of the order
+        on timestamp, as a data series ordered by timestamp will cluster
+        all the rows per day in contiguous blocks. Without that knowledge
+        the entire table must be read.
+       </para>
+
+       <para>
+        Default is <literal>on</literal>.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-enable-sort" xreflabel="enable_sort">
       <term><varname>enable_sort</varname> (<type>boolean</type>)
       <indexterm>
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 050e1e50bec..6d8a29e7411 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -4134,10 +4134,10 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind,
   <sect1 id="xfunc-optimization">
    <title>Function Optimization Information</title>
 
-  <indexterm zone="xfunc-optimization">
-   <primary>optimization information</primary>
-   <secondary>for functions</secondary>
-  </indexterm>
+   <indexterm zone="xfunc-optimization">
+    <primary>optimization information</primary>
+    <secondary>for functions</secondary>
+   </indexterm>
 
    <para>
     By default, a function is just a <quote>black box</quote> that the
@@ -4193,6 +4193,12 @@ supportfn(internal) returns internal
     so more things might be possible in future versions.
    </para>
 
+   <sect2 id="support-request-simplify">
+   <title>Simplification</title>
+   <indexterm>
+    <primary>optimization information</primary>
+    <secondary>for simplification</secondary>
+   </indexterm>
    <para>
     Some function calls can be simplified during planning based on
     properties specific to the function.  For example,
@@ -4240,6 +4246,11 @@ supportfn(internal) returns internal
     function's responsibility that the replacement Query be equivalent to
     normal execution of the target function.
    </para>
+   </sect2>
+
+
+   <sect2 id="support-request-selectivity">
+   <title>Selectivity</title>
 
    <para>
     For target functions that return <type>boolean</type>, it is often useful to estimate
@@ -4247,21 +4258,42 @@ supportfn(internal) returns internal
     function.  This can be done by a support function that implements
     the <literal>SupportRequestSelectivity</literal> request type.
    </para>
+   </sect2>
 
+   <sect2 id="support-request-cost">
+   <title>Variable Cost</title>
+   <indexterm>
+    <primary>optimization information</primary>
+    <secondary>for functions with variable cost</secondary>
+   </indexterm>
    <para>
     If the target function's run time is highly dependent on its inputs,
     it may be useful to provide a non-constant cost estimate for it.
     This can be done by a support function that implements
     the <literal>SupportRequestCost</literal> request type.
    </para>
+   </sect2>
 
+   <sect2 id="support-request-rows">
+   <title>Rows</title>
+   <indexterm>
+    <primary>optimization information</primary>
+    <secondary>for functions returning sets</secondary>
+   </indexterm>
    <para>
     For target functions that return sets, it is often useful to provide
     a non-constant estimate for the number of rows that will be returned.
     This can be done by a support function that implements
     the <literal>SupportRequestRows</literal> request type.
    </para>
+   </sect2>
 
+   <sect2 id="support-request-index-condition">
+   <title>Index condition</title>
+   <indexterm>
+    <primary>optimization information</primary>
+    <secondary>for functions in index condition</secondary>
+   </indexterm>
    <para>
     For target functions that return <type>boolean</type>, it may be possible to
     convert a function call appearing in <literal>WHERE</literal> into an indexable operator
@@ -4275,4 +4307,62 @@ supportfn(internal) returns internal
     To create such conditions, the support function must implement
     the <literal>SupportRequestIndexCondition</literal> request type.
    </para>
+   </sect2>
+
+   <sect2 id="support-request-monotonic">
+   <title>Monotonic functions</title>
+   <indexterm>
+    <primary>optimization information</primary>
+    <secondary>for monotonic functions</secondary>
+   </indexterm>
+   <para>
+    For target functions <literal>f(x)</literal> for which
+    <literal>f(x1) &lt; f(x2)</literal> and <literal>x1 &lt; x2 </literal> are defined,
+    <literal>SupportRequestMonotonic</literal> can be used to specify how
+    the order of <literal>f(x)</literal> can be infeered from the order of
+    <literal>x</literal>. For function with multiple parameters it can
+    specify how the function varies with respect to any number of parameters.
+    The function can depending on each parameter:
+
+    <itemizedlist>
+     <listitem>
+      <para>
+       <varname>MONOTONICFUNC_INCREASING</varname>: <literal>x1 &lt; x2</literal>
+       implies <literal>f(x1) &lt;= f(x2)</literal>
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       <varname>MONOTONICFUNC_DECREASING</varname>: <literal>x1 &lt; x2</literal>
+       implies <literal>f(x1) &gt;= f(x2)</literal>
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       <varname>MONOTONICFUNC_BOTH</varname>: both
+       <varname>MONOTONICFUNC_DECREASING</varname> and
+       <varname>MONOTONICFUNC_INCREASING</varname>, so
+       <literal>f(x1) = f(x2)</literal> for any valid
+       <literal>x1</literal> and <literal>x2</literal>.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       <varname>MONOTONICFUNC_NONE</varname>: the order of <literal>f(x)</literal>
+       cannot be inferred from the order of <literal>x</literal>
+      </para>
+     </listitem>
+    </itemizedlist>
+
+    A plan using a monotonic function on clauses such as
+    <literal>DISTINCT</literal>,
+    <literal>GROUP BY</literal>, <literal>ORDER BY</literal>,
+    <literal>PARTITION BY</literal>
+    can derive plans based on the order of one function argument
+   </para>
+
+   <para>
+    See also <xref linkend="guc-enable-slope"/>.
+   </para>
+   </sect2>
   </sect1>
-- 
2.53.0

