With One Argument
With Multiple Arguments
With Multiple Arguments and a Collector Class
With group(...)
Performance Tip: Avoid Repeated Subexpressions

For any query q, 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, 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. returns a query with the following characteristics:

  • Its value type is the same as exprn's result type.
  • Its value mapper is identical to exprn.
  • If exprn does not contain an aggregate function, then's output consists of successive results of exprn, evaluated using each successive record of q's output.
  • If exprn contains an aggregate function, then 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 =>x);
const query<float> products =>x * points->y);

// The exprn uses an aggregate function, so the query produces one output only:
const query<double> total =>x));

// Okay, because points's value mapper is identical to some_points's value mapper.
// (Stylistically questionable though.)
const query<float> some_xs =>x);

// Also okay, because equivalent to the preceding example:
const query<float> some_xs_again =
    .where(points->y > 1.9f)

// Invalid: the exprn is not an abstract_mapper:
const query<float> threes =;  // wrong

// Okay, although the exprn doesn't mention points's value mapper:
const query<float> threes =<float>(3));

// Invalid: exprn refers to a value mapper that is not visible to it:
const query<bool> nonsense =
    .select(points->x == *interesting_numbers); // wrong
const query<int64_t> more_nonsense =
    .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 =
        .select(count(points->x == *interesting_numbers))