For any query q
, q
.select(
...)
builds a query whose values are extracted or computed from the values that
q
would have produced. Roughly speaking, expressions
passed as arguments to select(
...)
are to quince what expressions in a “select-list” are to SQL.
For any query q
, you can call q
.select(
exprn
)
, provided that:
exprn
is an abstract_mapper<
T
>
, for some mapped type T
(this is checked at compile time).
q
's value mapper will be visible
to exprn
.
q
.select(
exprn
)
returns a query
with the following characteristics:
exprn
's
result type.
exprn
.
exprn
does not contain an aggregate
function, then q
.select(
exprn
)
's output consists of successive
results of exprn
, evaluated using each
successive record of q
's output.
exprn
contains an aggregate function,
then q
.select(
exprn
)
produces exactly one record, evaluated
based on the totality of q
's output.
(This treatment of aggregate functions is SQL behaviour; quince just “passes it through” to the application.)
extern table<point> points; const query<point> some_points = points.where(points->y > 1.9f); extern const query<float> interesting_numbers; // Most typical cases. Each of these queries produces one float per point in points: // const query<float> xs = points.select(points->x); const query<float> products = points.select(points->x * points->y); // The exprn uses an aggregate function, so the query produces one output only: // const query<double> total = points.select(sum(points->x)); // Okay, because points's value mapper is identical to some_points's value mapper. // (Stylistically questionable though.) // const query<float> some_xs = some_points.select(points->x); // Also okay, because equivalent to the preceding example: // const query<float> some_xs_again = points .where(points->y > 1.9f) .select(points->x); // Invalid: the exprn is not an abstract_mapper: // const query<float> threes = points.select(3.0f); // wrong // Okay, although the exprn doesn't mention points's value mapper: // const query<float> threes = points.select(exprn_mapper<float>(3)); // Invalid: exprn refers to a value mapper that is not visible to it: // const query<bool> nonsense = points .select(points->x == *interesting_numbers); // wrong const query<int64_t> more_nonsense = points .select(count(points->x == *interesting_numbers)); // wrong // Okay: scalar() makes *interesting_numbers (aka the value mapper for interesting_numbers) // visible to any expression inside its subquery. // const query<int64_t> point_counts = interesting_numbers .select(scalar( points .select(count(points->x == *interesting_numbers)) ));