|
From: Gregory W. <gw...@co...> - 2004-05-10 14:29:19
|
Hi Bjorn,
I tried the suggest method and it didn't typecheck. (_case requires
Expr,
not ExprAggr). This seems unnecessarily restrictive; I would expect
_case
to be able to take both an Expr and ExprAggr in the conditional
position.
For my program I have a workaround, but in developing it I ran into an
interesting question. (The workaround is just to query the count first,
and if it is nonzero query for the maximum element.)
Assume I have a database with a single table, all of whose fields are
Strings.
In hdb, how can I count the number of records matching a condition? The
query would look something like
myquery = do
t <- table mytab
restrict (t!myfield .==. constant the_interesting_field_value)
u <- project ( <this is the problem> << count(t!myfield))
return u
The projection is where the trouble is again. (I understand that I could
return the entire list of match records and take the length, but if the
list
is long and all I want is the count, that is unreasonably inefficient.)
Since we don't have a field of type Int, how do we return the count?
The solution may be straightforward, since we just need a way to easily
make
a record with known fields. Something like
project(returnAs("foo", IntT, True) << count(t!myfield))
which would result in the query
SELECT COUNT(myfield) AS foo ...
This could also solve the problem of _max and _min returning nothing on
empty tables, if the column named in returnAs were nullable.
Is it possible to declare a fake table (not present in the database) and
use it as a field in project? Then I could say
project (fakecol << count(t!myfield))
where fakecol was a column of type nullable Int. That might would be
easy, and it would be easy to explain that DBDirect automatically made
row declarations for each table in the database, but to return synthetic
rows you have to declare them yourself.
Thank for your help.
Best Wishes,
Greg
On May 9, 2004, at 7:21 PM, Bjorn Bringert wrote:
> Gregory Wright wrote:
>> I have a question about how to query an empty table. (I have to query
>> the
>> table to find the maximum value of a field; if there are any entries
>> at all the
>> field is non-null.)
>> I used
>> last = do
>> events <- table event
>> restrict (events!sid .==. constant 1)
>> u <- project (cid << _max(events!cid))
>> return u
>> The fields are sid and cid, and the goal is to find the largest value
>> of cid. Since cid is non-null as a type, this gives an error if the
>> table
>> is empty.
>> If there are any entries at all in the table, there are over 100,000,
>> so I don't want to return the whole table just to see if it is
>> non-empty.
>> My question: is there a way to simply have the query return empty
>> list if the table is empty, in a way that typechecks, or
>
> You have found an problem is HaskellDB's type system that I don't think
> we were aware of. The result type of _max, _min, avg etc. should be
> nullable,
> since they seem to return NULL if the relation is empty. We'll look
> into that.
>
> One way of solving your problem is to do something like (not tested):
>
> -- return the max value of the expression, or 0 if the relation is
> empty
> safeMax e = _case [(count e .>. 0, _max e)] (constant 0)
>
> last = do
> events <- table event
> restrict (events!sid .==. constant 1)
> u <- project (cid << safeMax (events!cid))
> return u
>
|