Allow FOR UPDATE to appear after LIMIT/OFFSET to match MySQL syntax and as
authorBruce Momjian <bruce@momjian.us>
Wed, 28 Aug 2002 14:35:37 +0000 (14:35 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 28 Aug 2002 14:35:37 +0000 (14:35 +0000)
a more logical ordering.

doc/src/sgml/ref/select.sgml
doc/src/sgml/ref/select_into.sgml
doc/src/sgml/sql.sgml
src/backend/parser/gram.y

index 7a696491a68f7aebd09ec09fcc1c69871152df24..5fdaf90f0acd2ea46c1a970c2cdd2cd3832d72ee 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/select.sgml,v 1.56 2002/08/15 02:59:18 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/select.sgml,v 1.57 2002/08/28 14:35:37 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -28,9 +28,9 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replac
     [ 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> ] [, ...] ]
-    [ FOR UPDATE [ OF <replaceable class="PARAMETER">tablename</replaceable> [, ...] ] ]
     [ LIMIT { <replaceable class="PARAMETER">count</replaceable> | ALL } ]
     [ OFFSET <replaceable class="PARAMETER">start</replaceable> ]
+    [ FOR UPDATE [ OF <replaceable class="PARAMETER">tablename</replaceable> [, ...] ] ]
 
 where <replaceable class="PARAMETER">from_item</replaceable> can be:
 
@@ -107,9 +107,9 @@ where <replaceable class="PARAMETER">from_item</replaceable> can be:
       <term><replaceable class="PARAMETER">select</replaceable></term>
       <listitem>
        <para>
-       A select statement with all features except the ORDER BY, FOR UPDATE,
-       and LIMIT clauses (even those can be used when the select is
-       parenthesized).
+       A select statement with all features except the ORDER BY, 
+       LIMIT/OFFSET, and FOR UPDATE clauses (even those can be used when the 
+       select is parenthesized).
        </para>
       </listitem>
      </varlistentry>
@@ -354,17 +354,17 @@ where <replaceable class="PARAMETER">from_item</replaceable> can be:
    (See <xref linkend="sql-except" endterm="sql-except-title">.)
   </para>
    
-  <para>
-   The FOR UPDATE clause allows the SELECT statement to perform 
-   exclusive locking of selected rows.
-  </para>
-   
   <para>
    The LIMIT clause allows a subset of the rows produced by the query
    to be returned to the user.
    (See <xref linkend="sql-limit" endterm="sql-limit-title">.)
   </para>
 
+  <para>
+   The FOR UPDATE clause allows the SELECT statement to perform 
+   exclusive locking of selected rows.
+  </para>
+   
   <para>
    You must have SELECT privilege to a table to read its values
    (See the <command>GRANT</command>/<command>REVOKE</command> statements).
@@ -666,8 +666,8 @@ SELECT name FROM distributors ORDER BY code;
 
     where
     <replaceable class="PARAMETER">table_query</replaceable>
-    specifies any select expression without an ORDER BY, FOR UPDATE,
-    or LIMIT clause.  (ORDER BY and LIMIT can be attached to a sub-expression
+    specifies any select expression without an ORDER BY, LIMIT, or FOR UPDATE
+    clause.  (ORDER BY and LIMIT can be attached to a sub-expression
     if it is enclosed in parentheses.  Without parentheses, these clauses
     will be taken to apply to the result of the UNION, not to its right-hand
     input expression.)
@@ -716,8 +716,8 @@ SELECT name FROM distributors ORDER BY code;
     
     where
     <replaceable class="PARAMETER">table_query</replaceable>
-    specifies any select expression without an ORDER BY, FOR UPDATE,
-    or LIMIT clause.
+    specifies any select expression without an ORDER BY, LIMIT, or 
+    FOR UPDATE clause.
    </para>
 
    <para>
@@ -757,8 +757,8 @@ SELECT name FROM distributors ORDER BY code;
     
     where
     <replaceable class="PARAMETER">table_query</replaceable>
-    specifies any select expression without an ORDER BY, FOR UPDATE,
-    or LIMIT clause.
+    specifies any select expression without an ORDER BY, LIMIT,
+    or FOR UPDATE clause.
    </para>
 
    <para>
index 13a8062268305477caa93c7d36b4c2a28e2b60ce..13e139ffbaa4fe8106e6682c4df507d2ebcae832 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/select_into.sgml,v 1.18 2002/04/23 02:07:16 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/select_into.sgml,v 1.19 2002/08/28 14:35:37 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -29,9 +29,9 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replac
     [ 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> ] [, ...] ]
-    [ FOR UPDATE [ OF <replaceable class="PARAMETER">tablename</replaceable> [, ...] ] ]
     [ LIMIT [ <replaceable class="PARAMETER">start</replaceable> , ] { <replaceable class="PARAMETER">count</replaceable> | ALL } ]
     [ OFFSET <replaceable class="PARAMETER">start</replaceable> ]
+    [ FOR UPDATE [ OF <replaceable class="PARAMETER">tablename</replaceable> [, ...] ] ]
 
 where <replaceable class="PARAMETER">from_item</replaceable> can be:
 
index 2c6247ff918f7454e84bca00ab3079ceeef05838..591e9aed3e8a7a710037ea0a516ce48073399d1e 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.26 2002/03/15 16:16:31 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/sql.sgml,v 1.27 2002/08/28 14:35:36 momjian Exp $
 -->
 
  <chapter id="sql">
@@ -863,9 +863,9 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replac
     [ 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> ] [, ...] ]
-    [ FOR UPDATE [ OF <replaceable class="PARAMETER">class_name</replaceable> [, ...] ] ]
     [ LIMIT { <replaceable class="PARAMETER">count</replaceable> | ALL } ]
     [ OFFSET <replaceable class="PARAMETER">start</replaceable> ]
+    [ FOR UPDATE [ OF <replaceable class="PARAMETER">class_name</replaceable> [, ...] ] ]
      </synopsis>
     </para>
 
index 0f512c7d31b32df62755d13d20ee3273ae1c8738..7fcc01a38f6a4c93b6da12c2ece65c136d22f98f 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.361 2002/08/27 04:55:08 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.362 2002/08/28 14:35:37 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -208,8 +208,8 @@ static void doNegateFloat(Value *v);
                                func_args_list, func_as, createfunc_opt_list
                                oper_argtypes, RuleActionList, RuleActionMulti,
                                opt_column_list, columnList, opt_name_list,
-                               sort_clause, sortby_list, index_params, index_list,
-                               name_list, from_clause, from_list, opt_array_bounds,
+                               sort_clause, opt_sort_clause, sortby_list, index_params,
+                               index_list,name_list, from_clause, from_list, opt_array_bounds,
                                qualified_name_list, any_name, any_name_list,
                                any_operator, expr_list, dotted_name, attrs,
                                target_list, update_target_list, insert_column_list,
@@ -4180,24 +4180,30 @@ select_with_parens:
                        | '(' select_with_parens ')'                    { $$ = $2; }
                ;
 
+/*
+ *     FOR UPDATE may be before or after LIMIT/OFFSET.
+ *     In <=7.2.X, LIMIT/OFFSET had to be after FOR UPDATE
+ *     We now support both orderings, but prefer LIMIT/OFFSET before FOR UPDATE
+ *     2002-08-28 bjm
+ */
 select_no_parens:
                        simple_select                                           { $$ = $1; }
-                       | select_clause sort_clause opt_for_update_clause opt_select_limit
+                       | select_clause sort_clause
                                {
-                                       insertSelectOptions((SelectStmt *) $1, $2, $3,
-                                                                               nth(0, $4), nth(1, $4));
+                                       insertSelectOptions((SelectStmt *) $1, $2, NIL,
+                                                                               NULL, NULL);
                                        $$ = $1;
                                }
-                       | select_clause for_update_clause opt_select_limit
+                       | select_clause opt_sort_clause for_update_clause opt_select_limit
                                {
-                                       insertSelectOptions((SelectStmt *) $1, NIL, $2,
-                                                                               nth(0, $3), nth(1, $3));
+                                       insertSelectOptions((SelectStmt *) $1, $2, $3,
+                                                                               nth(0, $4), nth(1, $4));
                                        $$ = $1;
                                }
-                       | select_clause select_limit
+                       | select_clause opt_sort_clause select_limit opt_for_update_clause
                                {
-                                       insertSelectOptions((SelectStmt *) $1, NIL, NIL,
-                                                                               nth(0, $2), nth(1, $2));
+                                       insertSelectOptions((SelectStmt *) $1, $2, $4,
+                                                                               nth(0, $3), nth(1, $3));
                                        $$ = $1;
                                }
                ;
@@ -4335,6 +4341,11 @@ opt_distinct:
                        | /*EMPTY*/                                                             { $$ = NIL; }
                ;
 
+opt_sort_clause:
+                       sort_clause                                                             { $$ = $1;}
+                       | /*EMPTY*/                                                             { $$ = NIL; }
+               ;
+
 sort_clause:
                        ORDER BY sortby_list                                    { $$ = $3; }
                ;