Page 1 of 1

Fyi using the RANK operator with a rva

Posted: Fri Aug 17, 2018 4:51 am
by steved
The RANK operator is extremely useful especially when used with rva's (relation valued attributes).
But in this context you have to be careful.
For example, given this relation:

Code: Select all

 REL{TUP{KEY. 1,ID "A"},
     TUP{KEY. 2,ID "A"}, 
     TUP{KEY. 3,ID "B"},
     TUP{KEY. 4,ID "B"},
     TUP{KEY. 5,ID "B"}} 
Suppose you want to GROUP attribute KEY. over attribute ID and create attribute RANK. using
attribute KEY. for the ranks. You want to end up with the following result (or at least close to it):

Code: Select all

RELATION {ID CHARACTER, GRP.RVA RELATION {KEY. INTEGER}, RANKS.RVA RELATION {KEY. INTEGER, RANK. INTEGER}} {
     TUPLE {ID "A", GRP.RVA RELATION {KEY. INTEGER} {
     TUPLE {KEY. 1},
     TUPLE {KEY. 2}
}, RANKS.RVA RELATION {KEY. INTEGER, RANK. INTEGER} {
     TUPLE {KEY. 1, RANK. 1},
     TUPLE {KEY. 2, RANK. 2}
}},
     TUPLE {ID "B", GRP.RVA RELATION {KEY. INTEGER} {
     TUPLE {KEY. 3},
     TUPLE {KEY. 4},
     TUPLE {KEY. 5}
}, RANKS.RVA RELATION {KEY. INTEGER, RANK. INTEGER} {
     TUPLE {KEY. 3, RANK. 1},
     TUPLE {KEY. 4, RANK. 2},
     TUPLE {KEY. 5, RANK. 3}
}}
}
Rva GRP.RVA is the result of GROUP using KEY. and rva RANKS.RVA is the relation with KEY.
and the rank attribute RANK.
You might think this query should do it:

Code: Select all

REL{TUP{KEY. 1,ID "A"},
    TUP{KEY. 2,ID "A"}, 
    TUP{KEY. 3,ID "B"},
    TUP{KEY. 4,ID "B"},
    TUP{KEY. 5,ID "B"}} 
    GROUP{KEY.} AS GRP.RVA 
    EXTEND {RANKS.RVA:=GRP.RVA{KEY.} RANK(ASC KEY. AS RANK.)}    
But if you execute the query you will get a fatal exception. The salient part of the error is this:

Code: Select all

org.reldb.rel.exceptions.ExceptionFatal: RS0452: Bad tuple. Heading TUPLE {KEY. INTEGER, RANK. INTEGER} says degree = 2 but tuple TUPLE {1} says degree = 1.
This error suggests that Rel can't determine the attribute(s) in rva GRP.RVA. GRP.RVA was initially
defined with just attribute KEY. but the ranking implies attributes KEY. and RANK. so which definition
should be used (perhaps Rel is also ignoring the relevance of RANKS.RVA which is where attribute RANK.
belongs).
In any case there are some simple ways to remove any ambiguities and get the query working.
One way is to show the degree of GROUP.RVA consistently. The degree of GROUP.RVA is 1 when its
formed so use a projection(with KEY.) with it in RANKS.RVA so the degree is always 1.

Code: Select all

REL{TUP{KEY. 1,ID "A"},
    TUP{KEY. 2,ID "A"}, 
    TUP{KEY. 3,ID "B"},
    TUP{KEY. 4,ID "B"},
    TUP{KEY. 5,ID "B"}} 
    GROUP{KEY.} AS GRP.RVA 
    EXTEND {RANKS.RVA:=GRP.RVA{KEY.} RANK(ASC KEY. AS RANK.)}
This query returns the result mentioned above.
Another way is to simply remove GRP.RVA from the result.

Code: Select all

(REL{TUP{KEY. 1,ID "A"},
    TUP{KEY. 2,ID "A"}, 
    TUP{KEY. 3,ID "B"},
    TUP{KEY. 4,ID "B"},
    TUP{KEY. 5,ID "B"}} 
    GROUP{KEY.} AS GRP.RVA 
    EXTEND {RANKS.RVA:=GRP.RVA RANK(ASC KEY. AS RANK.) }){ALL BUT GRP.RVA} 
This query returns just ID and RANKS.RVA and may be more appropriate when GRP.RVA is no longer needed.

Code: Select all

RELATION {ID CHARACTER, RANKS.RVA RELATION {KEY. INTEGER, RANK. INTEGER}} {
     TUPLE {ID "A", RANKS.RVA RELATION {KEY. INTEGER, RANK. INTEGER} {
     TUPLE {KEY. 1, RANK. 1},
     TUPLE {KEY. 2, RANK. 2}
}},
     TUPLE {ID "B", RANKS.RVA RELATION {KEY. INTEGER, RANK. INTEGER} {
     TUPLE {KEY. 3, RANK. 1},
     TUPLE {KEY. 4, RANK. 2},
     TUPLE {KEY. 5, RANK. 3}
}}
}
Also if you put a query with this error in an operator the operator will compile
with the error hidden until the operator is executed.

Re: Fyi using the RANK operator with a rva

Posted: Fri Aug 17, 2018 7:28 am
by Dave
You mentioned this causes a fatal error?

Code: Select all

REL{TUP{KEY. 1,ID "A"},
    TUP{KEY. 2,ID "A"}, 
    TUP{KEY. 3,ID "B"},
    TUP{KEY. 4,ID "B"},
    TUP{KEY. 5,ID "B"}} 
    GROUP{KEY.} AS GRP.RVA 
    EXTEND {RANKS.RVA:=GRP.RVA{KEY.} RANK(ASC KEY. AS RANK.)}    
I tried it and it works.

Re: Fyi using the RANK operator with a rva

Posted: Fri Aug 17, 2018 7:35 am
by steved
My mistake. This query, without the projection on GRP.RVA, will cause a fatal error:

Code: Select all

REL{TUP{KEY. 1,ID "A"},
    TUP{KEY. 2,ID "A"}, 
    TUP{KEY. 3,ID "B"},
    TUP{KEY. 4,ID "B"},
    TUP{KEY. 5,ID "B"}} 
    GROUP{KEY.} AS GRP.RVA 
    EXTEND {RANKS.RVA:=GRP.RVA RANK(ASC KEY. AS RANK.)}    

Re: Fyi using the RANK operator with a rva

Posted: Fri Aug 17, 2018 2:54 pm
by Dave
Looks like an even simpler example exhibits this bug.

This throws the fatal error:

Code: Select all

RELATION {TUPLE {RVA RELATION {TUPLE {K 1}}}} EXTEND {RR := RVA RANK (ASC K AS R)}
This works:

Code: Select all

RELATION {TUPLE {RVA RELATION {TUPLE {K 1}}}} EXTEND {RR := RVA {K} RANK (ASC K AS R)}
I've noted this in my "to do" list.