@@ -94,9 +94,9 @@ SELECT int4range(10, 20) * int4range(15, 25);
9494SELECT isempty(numrange(1, 5));
9595</programlisting>
9696
97- See <xref linkend="range-functions -table">
98- and <xref linkend="range-operators -table"> for complete lists of
99- functions and operators on range types.
97+ See <xref linkend="range-operators -table">
98+ and <xref linkend="range-functions -table"> for complete lists of
99+ operators and functions on range types.
100100 </para>
101101 </sect2>
102102
@@ -230,6 +230,9 @@ select '(3,7)'::int4range;
230230
231231-- includes only the single point 4
232232select '[4,4]'::int4range;
233+
234+ -- includes no points (and will be normalized to 'empty')
235+ select '[4,4)'::int4range;
233236</programlisting>
234237 </para>
235238 </sect2>
@@ -277,7 +280,7 @@ SELECT numrange(NULL, 2.2);
277280 <para>
278281 A discrete range is one whose element type has a well-defined
279282 <quote>step</quote>, such as <type>INTEGER</type> or <type>DATE</type>.
280- In these types two elements can be said to be adjacent, since there are
283+ In these types two elements can be said to be adjacent, when there are
281284 no valid values between them. This contrasts with continuous ranges,
282285 where it's always (or almost always) possible to identify other element
283286 values between two given values. For example, a range over the
@@ -301,18 +304,12 @@ SELECT numrange(NULL, 2.2);
301304 <para>
302305 A discrete range type should have a <firstterm>canonicalization</>
303306 function that is aware of the desired step size for the element type.
304- The canonicalization function is charged with converting values of the
305- range type to have consistently inclusive or exclusive bounds.
306- The canonicalization function takes an input range value, and
307- must return an equivalent range value that may have a different
308- formatting. The canonical output for two values that are equivalent, like
309- <literal>[1, 7]</literal> and <literal>[1, 8)</literal>, must be identical.
310- It doesn't matter which representation you choose to be the canonical one,
311- so long as two equivalent values with different formattings are always
312- mapped to the same value with the same formatting. If a canonicalization
313- function is not specified, then ranges with different formatting
314- will always be treated as unequal, even though they might represent the
315- same set of values.
307+ The canonicalization function is charged with converting equivalent values
308+ of the range type to have identical representations, in particular
309+ consistently inclusive or exclusive bounds.
310+ If a canonicalization function is not specified, then ranges with different
311+ formatting will always be treated as unequal, even though they might
312+ represent the same set of values in reality.
316313 </para>
317314
318315 <para>
@@ -331,28 +328,64 @@ SELECT numrange(NULL, 2.2);
331328 Users can define their own range types. The most common reason to do
332329 this is to use ranges over subtypes not provided among the built-in
333330 range types.
334- For example, to define a new range type of subtype <type>DOUBLE
335- PRECISION</type>:
331+ For example, to define a new range type of subtype <type>float8</type>:
336332
337333<programlisting>
338- CREATE TYPE FLOATRANGE AS RANGE (
339- SUBTYPE = DOUBLE PRECISION
334+ CREATE TYPE floatrange AS RANGE (
335+ subtype = float8,
336+ subtype_diff = float8mi
340337);
341338
342339SELECT '[1.234, 5.678]'::floatrange;
343340</programlisting>
344341
345- Because <type>DOUBLE PRECISION </type> has no meaningful
342+ Because <type>float8 </type> has no meaningful
346343 <quote>step</quote>, we do not define a canonicalization
347- function.
344+ function in this example.
345+ </para>
346+
347+ <para>
348+ If the subtype is considered to have discrete rather than continuous
349+ values, the <command>CREATE TYPE</> command should specify a
350+ <literal>canonical</> function.
351+ The canonicalization function takes an input range value, and must return
352+ an equivalent range value that may have different bounds and formatting.
353+ The canonical output for two ranges that represent the same set of values,
354+ for example the integer ranges <literal>[1, 7]</literal> and <literal>[1,
355+ 8)</literal>, must be identical. It doesn't matter which representation
356+ you choose to be the canonical one, so long as two equivalent values with
357+ different formattings are always mapped to the same value with the same
358+ formatting. In addition to adjusting the inclusive/exclusive bounds
359+ format, a canonicalization function might round off boundary values, in
360+ case the desired step size is larger than what the subtype is capable of
361+ storing. For instance, a range type over <type>timestamp</> could be
362+ defined to have a step size of an hour, in which case the canonicalization
363+ function would need to round off bounds that weren't a multiple of an hour,
364+ or perhaps throw an error instead.
348365 </para>
349366
350367 <para>
351368 Defining your own range type also allows you to specify a different
352- operator class or collation to use, so as to change the sort ordering
353- that determines which values fall into a given range. You might also
354- choose to use a different canonicalization function, either to change
355- the displayed format or to modify the effective <quote>step size</>.
369+ subtype B-tree operator class or collation to use, so as to change the sort
370+ ordering that determines which values fall into a given range.
371+ </para>
372+
373+ <para>
374+ In addition, any range type that is meant to be used with GiST indexes
375+ should define a subtype difference, or <literal>subtype_diff</>, function.
376+ (A GiST index will still work without <literal>subtype_diff</>, but it is
377+ likely to be considerably less efficient than if a difference function is
378+ provided.) The subtype difference function takes two input values of the
379+ subtype, and returns their difference (i.e., <replaceable>X</> minus
380+ <replaceable>Y</>) represented as a <type>float8</> value. In our example
381+ above, the function that underlies the regular <type>float8</> minus
382+ operator can be used; but for any other subtype, some type conversion would
383+ be necessary. Some creative thought about how to represent differences as
384+ numbers might be needed, too. To the greatest extent possible, the
385+ <literal>subtype_diff</> function should agree with the sort ordering
386+ implied by the selected operator class and collation; that is, its result
387+ should be positive whenever its first argument is greater than its second
388+ according to the sort ordering.
356389 </para>
357390
358391 <para>
@@ -366,18 +399,37 @@ SELECT '[1.234, 5.678]'::floatrange;
366399
367400 <indexterm>
368401 <primary>range type</primary>
369- <secondary>GiST index </secondary>
402+ <secondary>indexes on </secondary>
370403 </indexterm>
371404
372405 <para>
373- GiST indexes can be applied to columns of range types. For instance:
406+ GiST indexes can be created for table columns of range types.
407+ For instance:
374408<programlisting>
375409CREATE INDEX reservation_idx ON reservation USING gist (during);
376410</programlisting>
377- This index may speed up queries
378- involving <literal>&&</literal>
379- (overlaps), <literal>@></literal> (contains), and other boolean
380- operators listed in <xref linkend="range-operators-table">.
411+ A GiST index can accelerate queries involving these range operators:
412+ <literal>=</>,
413+ <literal>&&</>,
414+ <literal><@</>,
415+ <literal>@></>,
416+ <literal><<</>,
417+ <literal>>></>,
418+ <literal>-|-</>,
419+ <literal>&<</>, and
420+ <literal>&></>
421+ (see <xref linkend="range-operators-table"> for more information).
422+ </para>
423+
424+ <para>
425+ In addition, B-tree and hash indexes can be created for table columns of
426+ range types. For these index types, basically the only useful range
427+ operation is equality. There is a B-tree sort ordering defined for range
428+ values, with corresponding <literal><</> and <literal>></> operators,
429+ but the ordering is rather arbitrary and not usually useful in the real
430+ world. Range types' B-tree and hash support is primarily meant to
431+ allow sorting and hashing internally in queries, rather than creation of
432+ actual indexes.
381433 </para>
382434 </sect2>
383435
0 commit comments