For any query
builds a query whose values are extracted or computed from the values that
q would have produced. Roughly speaking, expressions
passed as arguments to
are to quince what expressions in a “select-list” are to SQL.
For any query
q, you can call
), provided that:
>, for some mapped type
T(this is checked at compile time).
q's value mapper will be visible
) returns a
with the following characteristics:
exprn's result type.
exprndoes not contain an aggregate function, then
)'s output consists of successive results of
exprn, evaluated using each successive record of
exprncontains an aggregate function, then
)produces exactly one record, evaluated based on the totality of
(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)) ));