Chapter 10. Built-in Table-valued Functions
Built-in table-valued functions are similar to selectable stored procedures. They accept scalar inputs and produce one or more rows as output.
Syntax
<built-in-table-function> ::=
<generate-series-function> <correlation-or-recognition>
| <unlist-table-function> <correlation-or-recognition>
<correlation-or-recognition> ::=
[AS] _correlation-name_ [ ( _column-name_ ) ] ①
- ①①
This is a simplified form of
<correlation-or-recognition>used in chapter Chapter 6, Data Manipulation (DML) Statements.
| Parameter | Description |
|---|---|
correlation-name | Name of the derived table. Contrary to subquery-based derived tables, the correlation name is required! |
column-name | Name of the column of the derived table. Depending on the use of the derived table, specifying the column name may be necessary. If not specified, the column will have no name and cannot be referenced, but it will receive an alias derived from the function name in the result set of a top-level query. |
For user-defined table-valued functions — a.k.a. selectable stored procedures, see Section 5.9.1, “CREATE PROCEDURE”, Section 6.1.3.2, “Selecting FROM a stored procedure”, and Section 7.2.2, “Types of Stored Procedures”.
10.1. General Purpose Table-valued Functions
10.1.1. GENERATE_SERIES()
Returns a table with a series of numbers within a specified interval.
Syntax
<generate-series> ::=
<generate-series-function> <correlation-or-recognition>
<generate-series-function> ::=
GENERATE_SERIES(start, limit [, step])
<correlation-or-recognition> ::=
!! See Table-valued functions syntax !!
GENERATE_SERIES Function Parameters| Parameter | Description |
|---|---|
start | Start or first value of the series. Expression of an integer or fixed point data type. |
limit | End or upper limit of the series. Expression of an integer or fixed point data type. |
step | Non-zero value to add to produce the next value.
Default is |
The function GENERATE_SERIES returns a table with a column of datatype BIGINT, INT128, NUMERIC(18, x), NUMERIC(38, x), where the precision (or type) is determined by the widest type, and the scale is determined by the maximum scale of the function arguments.
If start greater than limit and a positive step value is specified, an empty table is returned.
If start less than limit and a negative step value is specified, an empty table is returned.
The series stops once the generated value crosses (exceeds) the limit value.
If the step argument is zero, an error is raised.
GENERATE_SERIESGENERATE_SERIES is not a reserved word, and this can result in ambiguity if a stored procedure GENERATE_SERIES exists on the search path.
Firebird will use the GENERATE_SERIES built-in function for calls with two or three arguments if the correlation clause (AS …) is present.
For one argument, or four or more arguments, it will call the stored procedure GENERATE_SERIES.
However, if you leave out the correlation clause, it will select from the procedure GENERATE_SERIES, which might be unexpected.
If you need to select from a selectable stored procedure GENERATE_SERIES with two or three arguments and have to provide a correlation, then you need to qualify the procedure with its schema (e.g. PUBLIC.GENERATE_SERIES).
10.1.1.1. GENERATE_SERIES Examples
select Nfrom generate_series(1, 3) as S(N);select Nfrom generate_series(3, 1, -1) as S(N);select Nfrom generate_series(0, 9.9, 0.1) as S(N);selectdateadd(N minute to timestamp '2025-01-01 12:00') as START_TIME,dateadd(N minute to timestamp '2025-01-01 12:00:59.9999') as FINISH_TIMEfrom generate_series(0, 59) as S(N);
10.1.2. UNLIST()
Splits a string into multiple rows with a single column.
Syntax
<unlist> ::= <unlist-table-function> <correlation-or-recognition>
<unlist-table-function> ::=
UNLIST ( input [ , separator ] [<unlist-type-conversion>] )
<type-conversion> ::= RETURNING <domain_or_non_array_type>
<domain_or_non_array_type> ::=
!! See Scalar Data Types Syntax !!
<correlation-or-recognition> ::=
!! See Table-valued functions syntax !!
UNLIST Function Parameters| Parameter | Description |
|---|---|
input | Expression of a string or blob type; input to be split. |
separator | Expression of a string or blob type;
separator (delimiter) of the input.
If not specified, Length cannot exceed 32KiB. |
domain_or_non_array_type | Datatype of the output column.
Behaves as if Section 8.5.1, “ If not specified, |
The UNLIST function does the opposite of the aggregate function Section 9.3.5, “LISTAGG()”: splitting a string into rows.
A shorter form of UNLIST is available for use with Section 4.2.3.2, “IN”.
UNLISTUNLIST is not a reserved word, and this can result in ambiguity if a stored procedure UNLIST exists on the search path.
Firebird will use the UNLIST built-in function for calls with one or two arguments if the correlation clause (AS …) is present.
For three or more arguments, it will call the stored procedure UNLIST.
However, if you leave out the correlation clause, it will select from the procedure UNLIST, which might be unexpected.
If you need to select from a selectable stored procedure UNLIST with one or two arguments and have to provide a correlation, then you need to qualify the procedure with its schema (e.g. PUBLIC.UNLIST).
10.1.2.1. UNLIST Examples
select * from unlist('1,2,3,4,5') as U;-- Produce INTEGERs instead of CHARselect * from unlist('100:200:300:400:500', ':' RETURNING INT) AS U;select U.* from unlist('text1,text2,text3') as U;-- The second and third value produced start with a spaceselect C0 from unlist('text1, text2, text3') as U(C0);select U.C0 from unlist('text1,text2,text3') as U(C0);-- This does the same as DEPT_NO in ('120', '900')select EMP_NO from EMPLOYEEwhere DEPT_NO in (select * from unlist('120,900') as depts);-- The same but with the short form IN UNLISTselect EMP_NO from EMPLOYEEwhere DEPT_NO in unlist('120,900');-- "Column unknown" error as no explict column-name is defined-- -> default alias UNLIST only exists on outputselect UNLIST from unlist('UNLIST,A,S,A') as A;-- "Procedure unknown" error as no correlation-name is definedselect * from unlist('A,B,C')
See alsoSection 9.3.5, “LISTAGG()”