Skip to content

Commit

Permalink
#181 Added extra section with full select syntax
Browse files Browse the repository at this point in the history
This is a first step in addressing the current incompleteness/simplified syntax used in the SELECt section.
  • Loading branch information
mrotteveel committed May 8, 2023
1 parent 91c3714 commit 0abf46d
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 1 deletion.
182 changes: 181 additions & 1 deletion src/docs/asciidoc/en/refdocs/fblangref50/_fblangref50-dml.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ FROM
====
The above syntax is not the full `SELECT` syntax.
For documentation reasons, we attempt to build out the syntax in later sections.
If you find any errors in the syntax, or want to suggest a better way to represent the syntax, please let us know on https://github.com/FirebirdSQL/firebird-documentation[^]
The full SELECT syntax can be found below, in <<fblangref50-dml-select-full-syntax>>.
====

The `SELECT` statement retrieves data from the database and hands them to the application or the enclosing SQL statement.
Expand Down Expand Up @@ -2801,6 +2801,8 @@ The optional `DISTINCT` keyword makes the default behaviour explicit.
Since Firebird 5.0, instead of the `<individual-select>`, Firebird also allows a parenthesized query expression which can contain `ORDER BY`, `OFFSET` and `FETCH` clauses.
Before we can correctly incorporate this in the syntax, the documentation of the `SELECT` syntax needs to be overhauled significantly.
Until that happens, we hope this note suffices.
See also <<fblangref50-dml-select-full-syntax>> for the full syntax.
====

Unions take their column names from the _first_ select query.
Expand Down Expand Up @@ -3867,6 +3869,184 @@ FROM
* A recursive reference cannot participate in an outer join.
* The maximum recursion depth is 1024.

[[fblangref50-dml-select-full-syntax]]
=== Full `SELECT` Syntax

The previous sections used incomplete or simplified fragments of the `SELECT` syntax.
Following is the full syntax.

[NOTE]
====
Where possible, the syntax below uses syntax names from the SQL standard, which do not necessarily match the syntax names in the Firebird source, nor those used in previous sections of this chapter.
In some cases, syntax productions have been collapsed, because the production in the SQL standard are very verbose as they are also used to add additional rules or definitions to a syntax element.
Although this is intended as the full syntax, some productions are not shown (e.g. `<value-expression>`) and assumed to be clear for the reader, and in some cases we take shortcuts like using `__query-name__` or `__column-alias__` fpr identifiers in a syntax production.
If you come across situations where these shortcuts do result in lack of clarity or other issues, let us know on https://github.com/FirebirdSQL/firebird-documentation[^] or on https://groups.google.com/g/firebird-devel[firebird-devel^].
====

[listing,subs="+quotes,attributes"]
----
<cursor-specification> ::=
<query-expression> [<updatability-clause>] [<lock-clause>]
<query-expression> ::=
[<with-clause>] <query-expression-body> [<order-by-clause>]
[{ <rows-clause>
| [<result-offset-clause>] [<fetch-first-clause>] }]
<with-clause> ::= WITH [RECURSIVE] <with-list>
<with-list> ::= <with-list-element> [, <with-list-element> ...]
<with-list-element> ::=
_query-name_ [(<column-name-list>)] AS (<query-expression>)
<column-name-list> ::= _column-name_ [, _column-name_ ...]
<query-expression-body> ::=
<query-term>
| <query-expression-body> UNION [{ DISTINCT | ALL }] <query-term>
<query-term> ::= <query-primary>
<query-primary> ::=
<query-specification>
| (<query-expression-body> [<order-by-clause>]
[<result-offset-clause>] [<fetch-first-clause>])
<query-specification> ::=
SELECT <limit-clause> [{ ALL | DISTINCT }] <select-list>
FROM <table-reference-list>
[WHERE <search-condition>]
[GROUP BY <value-expression> [, <value-expression> ...]]
[HAVING <search-condition>]
[WINDOW <window-definition-list>]
[PLAN <plan-expression>]
<limit-clause> ::= [FIRST <limit-expression>] [SKIP <limit-expression>]
<limit-expression> ::=
<integer-literal>
| <query-parameter>
| (<value-expression>)
<select-list> ::= { * | <select-sublist> [, <select-sublist> ...] }
<select-sublist> ::=
__table-alias__.*
| <value-expression> [[AS] _column-alias_]
<table-reference-list> ::= <table-reference> [, <table-reference> ...]
<table-reference> ::= <table-primary> | <joined-table>
<table-primary> ::=
<table-or-query-name> [<correlation-or-recognition>]
| [LATERAL] <derived-table> [<correlation-or-recognition>]
| (<joined-table>)
<table-or-query-name> ::=
_table-name_
| _query-name_
| \[__package-name__.]_procedure-name_ [(<procedure-args>)]
<procedure-args> ::= <value-expression [, <value-expression> ...]
<correlation-or-recognition> ::=
[AS] _correlation-name_ [(<column-name-list>)]
<derived-table> ::=
(<query-expression>)
<joined-table> ::=
<cross-join>
| <natural-join>
| <qualified-join>
<cross-join>
<table-reference> CROSS JOIN <table-primary>
<natural-join> ::=
<table-reference> NATURAL [<join-type>] JOIN <table-primary>
<join-type> ::= INNER | <outer-join-type> [OUTER]
<outer-join-type> :: = LEFT | RIGHT | FULL
<qualified-join> ::=
<table-reference> [<join-type>] JOIN <table-primary>
{ ON <search-condition>
| USING (<column-name-list>) }
<window-definition-list> ::=
<window-definition> [, <window-definition> ...]
<window-definition> ::=
_new-window-name_ AS (<window-specification-details>)
<window-specification-details> ::=
[_existing-window-name_]
[<window-partition-clause>]
[<order-by-clause>]
[<window-frame-clause>]
<window-partition-clause> ::=
PARTITION BY <value-expression> [, <value-expression> ...]
<order-by-clause> ::= ORDER BY <sort-specification-list>
<sort-specification-list> ::=
<sort-specification [, <sort-specification> ...]
<sort-specification> ::=
<value-expression> [{ ASC | DESC }] [NULLS { FIRST | LAST }]
<window-frame-clause> ::=
{RANGE | ROWS} <window-frame-extent> [<window-frame-exclusion>]
<window-frame-extent> ::=
<window-frame-start>
| BETWEEN <window-frame-bound-1> AND <window-frame-bound-2>
<window-frame-start> ::=
UNBOUNDED PRECEDING
| CURRENT ROW
| <value-expression> PRECEDING
<window-frame-bound-1> ::=
<window-frame-start>
| <value-expression> FOLLOWING
<window-frame-bound-2> ::=
UNBOUNDED FOLLOWING
| CURRENT ROW
| <value-expression> PRECEDING
| <value-expression> FOLLOWING
<window-frame-exclusion> ::=
EXCLUDE NO OTHERS
| EXCLUDE CURRENT ROW
| EXCLUDE GROUP
| EXCLUDE TIES
<rows-clause> ::= ROWS <value-expression> [TO <value-expression>]
<result-offset-clause> :: =
OFFSET <offset-fetch-expression> { ROW | ROWS }
<offset-fetch-expression> ::=
<integer-literal>
| <query-parameter>
<fetch-first-clause> ::=
[FETCH { FIRST | NEXT } [<offset-fetch-expression>] { ROW | ROWS } ONLY]
<updatability-clause> ::= FOR UPDATE [OF <column-name-list>]
<lock-clause> ::= WITH LOCK [SKIP LOCKED]
----

[[fblangref50-dml-insert]]
== `INSERT`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ a|* Documented "`standard`" plugin tables in new appendix <<fblangref50-appx07-p
* Documented that subroutines can access variables of their parent
* Simplified `CONTINUE` and `LEAVE` examples, by removing unnecessary `ELSE`
* Documented `PLAN`, `ORDER BY` and `ROWS` for `UPDATE OR INSERT` and `PLAN` and `ORDER BY` for `MERGE`
* Added <<fblangref50-dml-select-full-syntax>> as a first step to address current incomplete/simplified syntax used in <<fblangref50-dml-select>>
* ...

|0.1
Expand Down

0 comments on commit 0abf46d

Please sign in to comment.