Firebird Documentation IndexFirebird 2.1 Release NotesData Manipulation Language (DML) → Articles
Firebird Home Firebird Home Prev: Data Manipulation Language (DML)Firebird Documentation IndexUp: Data Manipulation Language (DML)Next: Procedural SQL (PSQL)

Articles

SELECT Statement & Expression Syntax
Data Type of an Aggregation Result
A Useful Trick with Date Literals

SELECT Statement & Expression Syntax

Dmitry Yemanov

About the semantics

  • A select statement is used to return data to the caller (PSQL module or the client program)

  • Select expressions retrieve parts of data that construct columns that can be in either the final result set or in any of the intermediate sets. Select expressions are also known as subqueries.

Syntax rules

  <select statement> ::=
    <select expression> [FOR UPDATE] [WITH LOCK]

  <select expression> ::=
    <query specification> [UNION [{ALL | DISTINCT}] <query specification>]

  <query specification> ::=
    SELECT [FIRST <value>] [SKIP <value>] <select list>
    FROM <table expression list>
    WHERE <search condition>
    GROUP BY <group value list>
    HAVING <group condition>
    PLAN <plan item list>
    ORDER BY <sort value list>
    ROWS <value> [TO <value>]

  <table expression> ::=
    <table name> | <joined table> | <derived table>

  <joined table> ::=
    {<cross join> | <qualified join>}

  <cross join> ::=
    <table expression> CROSS JOIN <table expression>

  <qualified join> ::=
    <table expression> [{INNER | {LEFT | RIGHT | FULL} [OUTER]}] JOIN <table expression>
    ON <join condition>

  <derived table> ::=
    '(' <select expression> ')'
    

Conclusions

  • FOR UPDATE mode and row locking can only be performed for a final dataset, they cannot be applied to a subquery

  • Unions are allowed inside any subquery

  • Clauses FIRST, SKIP, PLAN, ORDER BY, ROWS are allowed for any subquery

Notes

  • Either FIRST/SKIP or ROWS is allowed, but a syntax error is thrown if you try to mix the syntaxes

  • An INSERT statement accepts a select expression to define a set to be inserted into a table. Its SELECT part supports all the features defined for select statments/expressions

  • UPDATE and DELETE statements are always based on an implicit cursor iterating through its target table and limited with the WHERE clause. You may also specify the final parts of the select expression syntax to limit the number of affected rows or optimize the statement.

    Clauses allowed at the end of UPDATE/DELETE statements are PLAN, ORDER BY and ROWS.

Data Type of an Aggregation Result

Arno Brinkman

When aggregations, CASE evaluations and UNIONs for output columns are performed over a mix of comparable data types, the engine has to choose one data type for the result. The developer often has to prepare a variable or buffer for such results and is mystified when a request returns a data type exception. The rules followed by the engine in determining the data type for an output column under these conditions are explained here.

  1. Let DTS be the set of data types over which we must determine the final result data type.

  2. All of the data types in DTS shall be comparable.

  3. In the case that

    1. any of the data types in DTS is character string

      1. If all data types in DTS are fixed-length character strings, then the result is also a fixed-length character string; otherwise the result is a variable-length character string.

        The resulting string length, in characters, is equal to the maximum of the lengths, in characters, of the data types in DTS.

      2. The character set and collation used are taken from the data type of the first character string in DTS.

    2. all of the data types in DTS are exact numeric

      the result data type is exact numeric with scale equal to the maximum of the scales of the data types in DTS and precision equal to the maximum precision of all data types in DTS.

    3. any data type in DTS is approximate numeric

      each data type in DTS must be numeric, otherwise an error is thrown.

    4. any data type in DTS is a date/time data type

      every data type in DTS must be a date/time type having the same date/time type, otherwise an error is thrown.

    5. any data type in DTS is BLOB

      each data type in DTS must be BLOB and all with the same sub-type.

A Useful Trick with Date Literals

H. Borrie

In days gone by, before the advent of context variables like CURRENT_DATE, CURRENT_TIMESTAMP, et al., we had predefined date literals, such as 'NOW', 'TODAY', 'YESTERDAY' and so on. These predefined date literals survive in Firebird's SQL language set and are still useful.

In InterBase 5.x and lower, the following statement was “legal” and returned a DATE value ( remembering that the DATE type then was what is now TIMESTAMP):

select 'NOW' from rdb$database /* returns system date and time */
      

In a database of ODS 10 or higher, that statement returns the string 'NOW'. We have had to learn to cast the date literal to get the result we want:

select cast('NOW' as TIMESTAMP) from rdb$database
      

For a long time—probably since IB 6— there has been an undocumented “short expression syntax” for casting not just the predefined date/time literals but any date literals. Actually, it is defined in the standard. Most of us were just not aware that it was available. It takes the form <data type> <date literal>. Taking the CAST example above, the short syntax would be as follows:

select TIMESTAMP 'NOW' from rdb$database
      

This short syntax can participate in other expressions. The following example illustrates a date/time arithmetic operation on a predefined literal:

update mytable
  set OVERDUE = 'T'
  where DATE 'YESTERDAY' - DATE_DUE > 10
      
Prev: Data Manipulation Language (DML)Firebird Documentation IndexUp: Data Manipulation Language (DML)Next: Procedural SQL (PSQL)
Firebird Documentation IndexFirebird 2.1 Release NotesData Manipulation Language (DML) → Articles