mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Support ORDER BY ... NULLS FIRST/LAST, and add ASC/DESC/NULLS FIRST/NULLS LAST
per-column options for btree indexes. The planner's support for this is still pretty rudimentary; it does not yet know how to plan mergejoins with nondefault ordering options. The documentation is pretty rudimentary, too. I'll work on improving that stuff later. Note incompatible change from prior behavior: ORDER BY ... USING will now be rejected if the operator is not a less-than or greater-than member of some btree opclass. This prevents less-than-sane behavior if an operator that doesn't actually define a proper sort ordering is selected.
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.140 2006/12/30 21:21:52 tgl Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.141 2007/01/09 02:14:09 tgl Exp $ -->
|
||||
<!--
|
||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||
-->
|
||||
@ -369,7 +369,17 @@
|
||||
<entry><type>int2</type></entry>
|
||||
<entry></entry>
|
||||
<entry>Zero if the index offers no sort order, otherwise the strategy
|
||||
number of the strategy operator that describes the sort order</entry>
|
||||
number of the strategy operator that describes the default
|
||||
(<literal>ASC</>) sort order</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>amdescorder</structfield></entry>
|
||||
<entry><type>int2</type></entry>
|
||||
<entry></entry>
|
||||
<entry>Zero if the index offers no sort order, otherwise the strategy
|
||||
number of the strategy operator that describes the <literal>DESC</>
|
||||
sort order</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
@ -2453,8 +2463,8 @@
|
||||
<entry><structfield>indisprimary</structfield></entry>
|
||||
<entry><type>bool</type></entry>
|
||||
<entry></entry>
|
||||
<entry>If true, this index represents the primary key of the table.
|
||||
(<structfield>indisunique</> should always be true when this is true.)</entry>
|
||||
<entry>If true, this index represents the primary key of the table
|
||||
(<structfield>indisunique</> should always be true when this is true)</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
@ -2487,7 +2497,7 @@
|
||||
of <literal>1 3</literal> would mean that the first and the third table
|
||||
columns make up the index key. A zero in this array indicates that the
|
||||
corresponding index attribute is an expression over the table columns,
|
||||
rather than a simple column reference.
|
||||
rather than a simple column reference
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
@ -2496,12 +2506,23 @@
|
||||
<entry><type>oidvector</type></entry>
|
||||
<entry><literal><link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.oid</literal></entry>
|
||||
<entry>
|
||||
For each column in the index key this contains the OID of
|
||||
For each column in the index key, this contains the OID of
|
||||
the operator class to use. See
|
||||
<link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link> for details
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>indoption</structfield></entry>
|
||||
<entry><type>int2vector</type></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
This is an array of <structfield>indnatts</structfield> values that
|
||||
store per-column flag bits. The meaning of the bits is defined by
|
||||
the index's access method
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>indexprs</structfield></entry>
|
||||
<entry><type>text</type></entry>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.39 2006/10/24 02:24:27 tgl Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.40 2007/01/09 02:14:10 tgl Exp $ -->
|
||||
|
||||
<chapter id="queries">
|
||||
<title>Queries</title>
|
||||
@ -1224,7 +1224,8 @@ SELECT DISTINCT ON (<replaceable>expression</replaceable> <optional>, <replaceab
|
||||
<synopsis>
|
||||
SELECT <replaceable>select_list</replaceable>
|
||||
FROM <replaceable>table_expression</replaceable>
|
||||
ORDER BY <replaceable>sort_expression1</replaceable> <optional>ASC | DESC</optional> <optional>, <replaceable>sort_expression2</replaceable> <optional>ASC | DESC</optional> ...</optional>
|
||||
ORDER BY <replaceable>sort_expression1</replaceable> <optional>ASC | DESC</optional> <optional>NULLS { FIRST | LAST }</optional>
|
||||
<optional>, <replaceable>sort_expression2</replaceable> <optional>ASC | DESC</optional> <optional>NULLS { FIRST | LAST }</optional> ...</optional>
|
||||
</synopsis>
|
||||
The sort expression(s) can be any expression that would be valid in the
|
||||
query's select list. An example is
|
||||
@ -1253,6 +1254,14 @@ SELECT a, b FROM table1 ORDER BY a + b, c;
|
||||
</footnote>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <literal>NULLS FIRST</> and <literal>NULLS LAST</> options can be
|
||||
used to determine whether nulls appear before or after non-null values
|
||||
in the sort ordering. By default, null values sort as if larger than any
|
||||
non-null value; that is, <literal>NULLS FIRST</> is the default for
|
||||
<literal>DESC</> order, and <literal>NULLS LAST</> otherwise.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For backwards compatibility with the SQL92 version of the standard,
|
||||
a <replaceable>sort_expression</> can instead be the name or number
|
||||
@ -1301,7 +1310,7 @@ SELECT a + b AS sum, c FROM table1 ORDER BY sum + c; -- wrong
|
||||
<synopsis>
|
||||
SELECT <replaceable>select_list</replaceable>
|
||||
FROM <replaceable>table_expression</replaceable>
|
||||
<optional> ORDER BY <replaceable>sort_expression1</replaceable> <optional>ASC | DESC</optional> <optional>, <replaceable>sort_expression2</replaceable> <optional>ASC | DESC</optional> ...</optional> </optional>
|
||||
<optional> ORDER BY ... </optional>
|
||||
<optional> LIMIT { <replaceable>number</replaceable> | ALL } </optional> <optional> OFFSET <replaceable>number</replaceable> </optional>
|
||||
</synopsis>
|
||||
</para>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.58 2006/09/16 00:30:17 momjian Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.59 2007/01/09 02:14:10 tgl Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -21,7 +21,7 @@ PostgreSQL documentation
|
||||
<refsynopsisdiv>
|
||||
<synopsis>
|
||||
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table</replaceable> [ USING <replaceable class="parameter">method</replaceable> ]
|
||||
( { <replaceable class="parameter">column</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [, ...] )
|
||||
( { <replaceable class="parameter">column</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
|
||||
[ WITH ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ]
|
||||
[ TABLESPACE <replaceable class="parameter">tablespace</replaceable> ]
|
||||
[ WHERE <replaceable class="parameter">predicate</replaceable> ]
|
||||
@ -187,6 +187,44 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>ASC</></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies ascending sort order (which is the default).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>DESC</></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies descending sort order.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>NULLS FIRST</></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies that nulls sort before non-nulls. This is the default
|
||||
when <literal>DESC</> is specified.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>NULLS LAST</></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies that nulls sort after non-nulls. This is the default
|
||||
when <literal>DESC</> is not specified.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">storage_parameter</replaceable></term>
|
||||
<listitem>
|
||||
@ -363,6 +401,21 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re
|
||||
linkend="xindex">.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For index methods that support ordered scans (currently, only B-tree),
|
||||
the optional clauses <literal>ASC</>, <literal>DESC</>, <literal>NULLS
|
||||
FIRST</>, and/or <literal>NULLS LAST</> can be specified to reverse
|
||||
the normal sort direction of the index. Since an ordered index can be
|
||||
scanned either forward or backward, it is not normally useful to create a
|
||||
single-column <literal>DESC</> index — that sort ordering is already
|
||||
available with a regular index. The value of these options is that
|
||||
multicolumn indexes can be created that match the sort ordering requested
|
||||
by a mixed-ordering query, such as <literal>SELECT ... ORDER BY x ASC, y
|
||||
DESC</>. The <literal>NULLS</> options are useful if you need to support
|
||||
<quote>nulls sort low</> behavior, rather than the default <quote>nulls
|
||||
sort high</>, in queries that depend on indexes to avoid sorting steps.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Use <xref linkend="sql-dropindex" endterm="sql-dropindex-title">
|
||||
to remove an index.
|
||||
@ -403,6 +456,13 @@ CREATE INDEX lower_title_idx ON films ((lower(title)));
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To create an index with non-default sort ordering of nulls:
|
||||
<programlisting>
|
||||
CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST);
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To create an index with non-default fill factor:
|
||||
<programlisting>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.94 2006/12/01 20:49:53 tgl Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.95 2007/01/09 02:14:10 tgl Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -27,7 +27,7 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replac
|
||||
[ GROUP BY <replaceable class="parameter">expression</replaceable> [, ...] ]
|
||||
[ HAVING <replaceable class="parameter">condition</replaceable> [, ...] ]
|
||||
[ { UNION | INTERSECT | EXCEPT } [ ALL ] <replaceable class="parameter">select</replaceable> ]
|
||||
[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [, ...] ]
|
||||
[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
|
||||
[ LIMIT { <replaceable class="parameter">count</replaceable> | ALL } ]
|
||||
[ OFFSET <replaceable class="parameter">start</replaceable> ]
|
||||
[ FOR { UPDATE | SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT ] [...] ]
|
||||
@ -642,7 +642,7 @@ HAVING <replaceable class="parameter">condition</replaceable>
|
||||
<para>
|
||||
The optional <literal>ORDER BY</literal> clause has this general form:
|
||||
<synopsis>
|
||||
ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [, ...]
|
||||
ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...]
|
||||
</synopsis>
|
||||
<replaceable class="parameter">expression</replaceable> can be the
|
||||
name or ordinal number of an output column
|
||||
@ -652,8 +652,8 @@ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC |
|
||||
|
||||
<para>
|
||||
The <literal>ORDER BY</literal> clause causes the result rows to
|
||||
be sorted according to the specified expressions. If two rows are
|
||||
equal according to the leftmost expression, the are compared
|
||||
be sorted according to the specified expression(s). If two rows are
|
||||
equal according to the leftmost expression, they are compared
|
||||
according to the next expression and so on. If they are equal
|
||||
according to all specified expressions, they are returned in
|
||||
an implementation-dependent order.
|
||||
@ -697,6 +697,8 @@ SELECT name FROM distributors ORDER BY code;
|
||||
<literal>ORDER BY</> clause. If not specified, <literal>ASC</> is
|
||||
assumed by default. Alternatively, a specific ordering operator
|
||||
name may be specified in the <literal>USING</> clause.
|
||||
An ordering operator must be a less-than or greater-than
|
||||
member of some btree operator family.
|
||||
<literal>ASC</> is usually equivalent to <literal>USING <</> and
|
||||
<literal>DESC</> is usually equivalent to <literal>USING ></>.
|
||||
(But the creator of a user-defined data type can define exactly what the
|
||||
@ -705,9 +707,14 @@ SELECT name FROM distributors ORDER BY code;
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The null value sorts higher than any other value. In other words,
|
||||
with ascending sort order, null values sort at the end, and with
|
||||
descending sort order, null values sort at the beginning.
|
||||
If <literal>NULLS LAST</> is specified, null values sort after all
|
||||
non-null values; if <literal>NULLS FIRST</> is specified, null values
|
||||
sort before all non-null values. If neither is specified, the default
|
||||
behavior is <literal>NULLS LAST</> when <literal>ASC</> is specified
|
||||
or implied, and <literal>NULLS FIRST</> when <literal>DESC</> is specified
|
||||
(thus, the default is to act as though nulls are larger than non-nulls).
|
||||
When <literal>USING</> is specified, the default nulls ordering depends
|
||||
on whether the operator is a less-than or greater-than operator.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/select_into.sgml,v 1.38 2006/09/16 00:30:20 momjian Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/select_into.sgml,v 1.39 2007/01/09 02:14:10 tgl Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -28,7 +28,7 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replac
|
||||
[ GROUP BY <replaceable class="PARAMETER">expression</replaceable> [, ...] ]
|
||||
[ HAVING <replaceable class="PARAMETER">condition</replaceable> [, ...] ]
|
||||
[ { UNION | INTERSECT | EXCEPT } [ ALL ] <replaceable class="PARAMETER">select</replaceable> ]
|
||||
[ ORDER BY <replaceable class="PARAMETER">expression</replaceable> [ ASC | DESC | USING <replaceable class="PARAMETER">operator</replaceable> ] [, ...] ]
|
||||
[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
|
||||
[ LIMIT { <replaceable class="PARAMETER">count</replaceable> | ALL } ]
|
||||
[ OFFSET <replaceable class="PARAMETER">start</replaceable> ]
|
||||
[ FOR { UPDATE | SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT ] [...] ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.42 2006/09/16 00:30:15 momjian Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.43 2007/01/09 02:14:10 tgl Exp $ -->
|
||||
|
||||
<chapter id="sql-intro">
|
||||
<title>SQL</title>
|
||||
@ -860,7 +860,7 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replac
|
||||
[ GROUP BY <replaceable class="PARAMETER">expression</replaceable> [, ...] ]
|
||||
[ HAVING <replaceable class="PARAMETER">condition</replaceable> [, ...] ]
|
||||
[ { UNION | INTERSECT | EXCEPT } [ ALL ] <replaceable class="PARAMETER">select</replaceable> ]
|
||||
[ ORDER BY <replaceable class="PARAMETER">expression</replaceable> [ ASC | DESC | USING <replaceable class="PARAMETER">operator</replaceable> ] [, ...] ]
|
||||
[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
|
||||
[ LIMIT { <replaceable class="PARAMETER">count</replaceable> | ALL } ]
|
||||
[ OFFSET <replaceable class="PARAMETER">start</replaceable> ]
|
||||
[ FOR { UPDATE | SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT ] [...] ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.53 2006/12/01 23:46:46 tgl Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.54 2007/01/09 02:14:10 tgl Exp $ -->
|
||||
|
||||
<sect1 id="xindex">
|
||||
<title>Interfacing Extensions To Indexes</title>
|
||||
@ -289,13 +289,17 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
By the way, the <structfield>amorderstrategy</structfield> column
|
||||
in <classname>pg_am</> tells whether
|
||||
the index method supports ordered scans. Zero means it doesn't; if it
|
||||
does, <structfield>amorderstrategy</structfield> is the strategy
|
||||
number that corresponds to the ordering operator. For example, B-tree
|
||||
has <structfield>amorderstrategy</structfield> = 1, which is its
|
||||
<quote>less than</quote> strategy number.
|
||||
By the way, the <structfield>amorderstrategy</structfield> and
|
||||
<structfield>amdescorder</structfield> columns in <classname>pg_am</> tell
|
||||
whether the index method supports ordered scans. Zeroes mean it doesn't;
|
||||
if it does, <structfield>amorderstrategy</structfield> is the strategy
|
||||
number that corresponds to the default ordering operator, and
|
||||
<structfield>amdescorder</structfield> is the strategy number for the
|
||||
ordering operator of an index column that has the <literal>DESC</> option.
|
||||
For example, B-tree has <structfield>amorderstrategy</structfield> = 1,
|
||||
which is its <quote>less than</quote> strategy number, and
|
||||
<structfield>amdescorder</structfield> = 5, which is its
|
||||
<quote>greater than</quote> strategy number.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
|
Reference in New Issue
Block a user