Relix

Language reference

source … from generator (generated series)

Syntax

source <Name> from generator { name: "<generator>", <argument>: "<value>", … };

source Small from generator { name: "Range", lo: "1", hi: "10" };
source Whole from generator { name: "Naturals" };
source Prime from generator { name: "Primes" };

Description

A generator is a relation whose rows the engine makes up rather than reads from anywhere: the numbers from 1 to 10, every whole number, every prime. It is declared like any other source, naming the series. Nothing has to be stored and nothing has to be fetched, so it is always available.

It is useful as the spine of something else — a calendar to left-join sparse readings onto, a set of ids to probe with, the rows of a test fixture — and, for the two generators that never end, as a source that a bound turns into a finite relation.

Technical Description

name selects the generator, and every other entry is an argument to it. Each argument is written as a double-quoted string. Three generators are built in:

GeneratorArgumentsRowsEnds?
Rangelo and hi (required, integers); step (optional, a positive integer, default 1)one column n: lo, lo + step, … up to hi, inclusive; none when lo is greater than hiyes
Naturalsnoneone column n: 0, 1, 2, …no
Primesnoneone column n: 2, 3, 5, 7, …no

Each generator owns its heading, so a generator source declares no schema. All three produce a single n column of type NUMBER, in ascending order and without duplicates.

An unknown generator name, a missing required argument, or an argument that is not an integer is an error, naming the generator.

An unbounded generator is a bounded relation once a bound sits above it. Naturals and Primes have no last row, so a query that would have to read them whole — a grouping, a sort, a distinct count — is refused when it is planned, while one that stops is fine: λ 5 (Naturals) pulls five rows, and σ n < 20 (Primes) is turned by the optimizer into a generator that stops at 20 (see optimizer, rule GEN-001). The relix.relations catalog reports each generator's boundedness.

Examples

The numbers 1 to 10 in steps of 3:

Query
source Small from generator { name: "Range", lo: "1", hi: "10", step: "3" };

query { Small };
Result
 n 
 ──
  1
  4
  7
 10
(4 rows)

The first three whole numbers, from a series that never ends:

Query
source Whole from generator { name: "Naturals" };

query { λ 3 (Whole) };
Result
 n
 ─
 0
 1
 2
(3 rows)

A bound above the generator is enough:

source Whole from generator { name: "Naturals" };

query { σ n < 3 (Whole) };

The primes below 30, found by the engine stopping rather than by filtering a series that never ends:

source Prime from generator { name: "Primes" };

query { σ n < 30 (Prime) };

Limitations

Only the three generators above exist. A generator's arguments are fixed numbers: they cannot be read from another relation's columns.

A query that needs every row of an unbounded generator is refused instead of running without end.

Alternatives

For a generator of ids or dates to join against, Range is usually enough. For a set of rows you write out, an inline table.

See Also

source, inline-table, limit, relation catalog

Notes

Because the series is a function of its arguments, a generator always returns the same rows when asked again.