Re: Relation-valued attributes (again)

From: x y <compdb_at_hotmail.com>
Date: 8 Feb 2005 19:37:40 -0800
Message-ID: <6574f424.0502081937.33cb5627_at_posting.google.com>


hi Bryn,

jingleheimerschmitt_at_hotmail.com wrote in message news:<1107506247.516286.294330_at_g14g2000cwa.googlegroups.com>...
> Again, I am not advocating disallowing RVAs. Indeed, I think this
> example shows that they are actually *required*, given support for
> abitrarily typed user-defined operators (relational-valued ones in
> particular).

(I have been thinking you mean D group/ungroup for nest/unnest--am I mistaken?)

I understand from your last msg that you are doubting that ungroup is primitive--more on this below.
However I don't understand your choice of counterexample; I don't understand how it matters whether Op is a function or relation,
or whether you have relation-valued functions (you can always just insert an rva directly).
The point I was trying to make last msg was that 1. if you want T-join-Op then you can calculate it by join on a relation-Op or extend on a function-Op, and 2. if you want T-join-Op-unnested then why does it matter how you did the join?

But as I say, I seem to be missing something.

> > Interpreting Op as a relation mapping argument aid to (relation
> > valued) result, perhaps you mean
> > select T join ("Op" rename aid as id)
> > But this would have an (unnamed) rva so perhaps you mean
> > select (T join ("Op" rename aid as id)) unnest {all but oid}
> > This now looks like your rva add (extend) formulation below
> > but it doesn't help you get what you want without rvas.
> The latter, that is why I quoted the "join". It's only a join
> conceptually in that I'm combining the results from two relation-valued
> expressions. It's not a true join because I can't invoke an operator
> "foreach" tuple in the left operand.

Yes, I understood that it's not a join because Op is a function not a relation.

> > > Clearly this formulation is invalid because the right operand must
> be
> > > evaluated in the context of a tuple of the left operand.
> >
> > Not exactly; Op just needs an integer as its parameter.
> No, exactly. Try actually running this query as a true join, it can't
> be done, precisely because the right operand must be evaluated for
> every tuple in the left operand. Joins don't work this way, you
> evaluate each operand, and then evaluate the join.

Ditto.

> > > The query with
> > > RVAs is simply:
> > >
> > > select T add { Op(ID) RVA } unnest by { RVA };
> >
> > This only contains the same info as a join of T and Op if Op never
> > returns an empty relation.
> That may be (I'd have to think about that for a long time) but it is
> not relevant to the underlying idea.

Right; I thought it might be relevant to what you are trying to achieve with your example expression.
Re whether it "may be", see Date's Intro to DBS section 7.0 Grouping and Ungrouping.
By the way, I've never seen a proposal for GROUP PER, but it would be a way of putting empty values into ("back into" with respect to an UNGROUP) an rva.

> > In your case you allow functions returning relation values but you
> > don't allow relational values to be put inside relations;
> > then you complain that you can't express some queries.
> > Well, the queries you allowed just aren't the ones you wish you had.
> > The fault is not relational theory but in restricting expressions.
> > You allow an operator to return a value but you do not let those
> > values go where other values may go.
> You're proceeding from false assumptions here. My entire example
> requires RVAs. The point is that if we have RVAs we apparently need to
> introduce at least one new operator (unnest) to the relational algebra
> to deal with them.

One of the points I was trying to make is that even if ungroup is primitive, indeed even if it's not present, we can still have and use nested relations.
It is in this sense that i meant that disallowing them introduces unnecessary restrictions and hence is less simple. Consider the following relation variable values:

rint :=
mychar myint

     a          1
     b          2

rrel :=
mychar myrel

                myfloats
     a              1.0
                     2.0
                myfloats
     b              3.0

You are happy to stick ints into rint, why shouldn't you put relations into rrel?

One thing ints have going for them is you have special functionality built into the language:
aggregate operators for summarize and column operators for extend. So you can say
  SUMMARIZE rint ADD SUM(myint) AS summary But aggregation should be allowed for arbitrary types and appropriate functions, eg
  SUMMARIZE rint ADD PRODUCT(myint) AS summary
  SUMMARIZE rrel ADD UNION(myrel) AS summary Also, a basic system capability is a way to extract a value out of a relation
(I don't found how D does this),
eg sql coerces a one-column one-row table to a scalar in a scalar context.
Then one way to express
  ungroup (T add {Op(ID) RVA}) by RVA
is the single value in
  summarize
    (T add {Op(ID) RVA}) add {(RVA add {ID ID}) eachid})   union (eachid) as summary

(I will have more to say about the details of the primitiveness of group/ungroup, extend and summarize in a later msg.)

You may say, I am cheating, that ungroup is only non-primitive if I allow abitrarily typed aggregates and value extraction. I can only say that a system overall has not just operators from relations to relations but operators between relations and other types,
and if you don't treat any type as special (eg integers, or relations) and are thoroughly orthogonal in your use of types, then having added sensible primitives for those purposes also gives you ungroup.

Philip Received on Wed Feb 09 2005 - 04:37:40 CET

Original text of this message