Notice that some of the SQL functions are so-called "scalar functions"
(e.g. abs
) and others are so-called "aggregate
functions" (e.g. max
, count
).
That is a distinction in SQL semantics that quince simply passes through
to application code. So:
const query<float> abs_xs = points.select(abs(points->x)); const query<boost::optional<float>> max_x = points.select(max(points->x)); const query<double> sum_x = points.select(sum(points->x));
If you execute the query abs_xs
,
you get the absolute values of each x
in points
. There are
as many results as there are records in the the table.
If you execute max_x
,
you get the greatest of all the x
values in points
. That's
one result only. If points
is empty, then there is no greatest x
,
but there is still one result, viz. boost::none
. (That's because SQL's max
produces a single SQL NULL
, and quince's max()
passes it on.)
SQL's sum
also produces a single SQL NULL
when there is no input, but I made an editorial decision not to pass
that on. Quince's sum()
returns zero when there is nothing
to add up. So if points
is empty, the query sum_x
produces a single 0.0
.
We have seen some examples of queries that are guaranteed to produce just one computed result. Later we shall see that there are special means of executing such queries, and of embedding them in other queries.
exprn_mapper<boost::optional<
...>>
exprn_mapper<boost::optional<
...>>
provides the operators *
and ->
,
and the methods is_initialized()
and get_value_or()
, which you can use in the same way
as the corresponding features of optional_mapper<
...>
[8]:
const query<float> max_x_or_zero = points.select(max(points->x).get_value_or(0.f));
Here max(points->x).get_value_or(0.f)
is
a server-side expression, i.e. the DBMS evaluates it all. In this context,
get_value_or()
is a wrapper for SQL's coalesce
.
This is the technique that sum()
uses internally.
[8]
In fact exprn_mapper<boost::optional<
T
>>
is a subclass of optional_mapper<
T
>
, so if you want to write code that
deals polymorphically with both types, use optional_mapper<
T
>
.