From 6077db92c2575d4011b9368ac77808a69a0a785f Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 28 Aug 2002 14:35:37 +0000 Subject: [PATCH] Allow FOR UPDATE to appear after LIMIT/OFFSET to match MySQL syntax and as a more logical ordering. --- doc/src/sgml/ref/select.sgml | 32 ++++++++++++++-------------- doc/src/sgml/ref/select_into.sgml | 4 ++-- doc/src/sgml/sql.sgml | 4 ++-- src/backend/parser/gram.y | 35 ++++++++++++++++++++----------- 4 files changed, 43 insertions(+), 32 deletions(-) diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index 7a696491a6..5fdaf90f0a 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -1,5 +1,5 @@ @@ -28,9 +28,9 @@ SELECT [ ALL | DISTINCT [ ON ( expressioncondition [, ...] ] [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ] [ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ] - [ FOR UPDATE [ OF tablename [, ...] ] ] [ LIMIT { count | ALL } ] [ OFFSET start ] + [ FOR UPDATE [ OF tablename [, ...] ] ] where from_item can be: @@ -107,9 +107,9 @@ where from_item can be: select - 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). @@ -354,17 +354,17 @@ where from_item can be: (See .) - - The FOR UPDATE clause allows the SELECT statement to perform - exclusive locking of selected rows. - - The LIMIT clause allows a subset of the rows produced by the query to be returned to the user. (See .) + + The FOR UPDATE clause allows the SELECT statement to perform + exclusive locking of selected rows. + + You must have SELECT privilege to a table to read its values (See the GRANT/REVOKE statements). @@ -666,8 +666,8 @@ SELECT name FROM distributors ORDER BY code; where table_query - 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 table_query - 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. @@ -757,8 +757,8 @@ SELECT name FROM distributors ORDER BY code; where table_query - 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. diff --git a/doc/src/sgml/ref/select_into.sgml b/doc/src/sgml/ref/select_into.sgml index 13a8062268..13e139ffba 100644 --- a/doc/src/sgml/ref/select_into.sgml +++ b/doc/src/sgml/ref/select_into.sgml @@ -1,5 +1,5 @@ @@ -29,9 +29,9 @@ SELECT [ ALL | DISTINCT [ ON ( expressioncondition [, ...] ] [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ] [ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ] - [ FOR UPDATE [ OF tablename [, ...] ] ] [ LIMIT [ start , ] { count | ALL } ] [ OFFSET start ] + [ FOR UPDATE [ OF tablename [, ...] ] ] where from_item can be: diff --git a/doc/src/sgml/sql.sgml b/doc/src/sgml/sql.sgml index 2c6247ff91..591e9aed3e 100644 --- a/doc/src/sgml/sql.sgml +++ b/doc/src/sgml/sql.sgml @@ -1,5 +1,5 @@ @@ -863,9 +863,9 @@ SELECT [ ALL | DISTINCT [ ON ( expressioncondition [, ...] ] [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ] [ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ] - [ FOR UPDATE [ OF class_name [, ...] ] ] [ LIMIT { count | ALL } ] [ OFFSET start ] + [ FOR UPDATE [ OF class_name [, ...] ] ] diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 0f512c7d31..7fcc01a38f 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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; } ; -- GitLab