As a first step we could do something like: basic_select_statement is:
> SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] > [ * | expression [ [ AS ] output_name ] [, ...] ] > [ FROM from_item [, ...] ] > [ WHERE condition ] > [ GROUP BY grouping_element [, ...] ] > [ HAVING condition [, ...] ] > [ WINDOW window_name AS ( window_definition ) [, ...] ] > full_select_statement is basic_select_statement with the following possible additional clauses tacked onto the end: [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | > LAST } ] [, ...] ] > [ LIMIT { count | ALL } ] > [ OFFSET start [ ROW | ROWS ] ] > [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] > [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name > [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ] > > and that's still not right because ORDER BY et al can't be attached to a > select_stmt that's the argument of a set operation, so really we'd need > a couple of levels of nonterminals before we get down to the basic > "SELECT expression FROM ..." part. Nor has the use of parentheses been > mentioned yet. > Then we can define the set clauses in terms of basic_select_stmt and parentheses-surrounded full_select_stmt. The result of the set clause is itself a type of basic_select_statement which can be made full by adding one or more of the additional clauses, including ORDER BY. David J.