We can use attrs
for other things as well.
Dynamic projections
For example, projecting from a dynamically generated list of attributes. If we want to project the attributes of S that are of type int
, say, then we could:
S{attrs(heading(S)[type="int"])}
STATUS |
---|
10 |
20 |
30 |
Or if we want to project the attributes of S that are not of type int
then we could:
S~{attrs(heading(S)[type="int"])}
SNO | SNAME | CITY |
---|---|---|
S1 | Smith | London |
S2 | Jones | Paris |
S3 | Blake | Paris |
S4 | Clark | London |
S5 | Adams | Athens |
Dynamic variables
We can also pass attrs
to schema
, which lets us select variables from the current schema (schema
giving us a single tuple containing an attr/value for each entry in the schema). If we want to get the variable named S, say, then we could:
schema{attrs(dee(attr:="S"))}.*
SNO | SNAME | STATUS | CITY |
---|---|---|---|
S1 | Smith | 20 | London |
S2 | Jones | 10 | Paris |
S3 | Blake | 30 | Paris |
S4 | Clark | 20 | London |
S5 | Adams | 30 | Athens |
Where you'll notice the S we selected was passed as a string and evaluated by attrs
at runtime.
Dynamic everything
And of course we can have a dynamic projection on a dynamically chosen relvar:
schema{attrs(dee(attr:="S"))}.*{attrs(heading(schema{attrs(dee(attr:="S"))}.*)[type="int"])}
STATUS |
---|
10 |
20 |
30 |