As the syntax is defined so far, all variables must be declared in the FROM statement of a query, and path expressions may only occur in the FROM statement. However it is often more convenient to use path expressions directly in the SELECT and WHERE clauses of query. For example, rather than writing
SELECT Z FROM X IN FRAGMENT, Y IN X.!owns[PERSON]name, Z IN X.fragment_id WHERE Y = "John" ;we would like to be able write
SELECT X.fragment_id FROM X IN FRAGMENT WHERE X.!owns[PERSON]name= "John" ;
In order to allow such queries we extend the definition of expressions to include class expressions:
<expression> ::= <class expression>
| <variable>
| <primitive value>
| <set of values>
;
When a class expression, say CE, occurs in a WHERE or a SELECT \
statement, it is equivalent having some new system generated
variable, say
in place of the class expression, and having the
declaration
IN CE in the FROM statement.
It is important to note that each occurrence of a class expression in a SELECT or WHERE statement is equivalent to a distinct new variable. For example the query
SELECT X.name
FROM X IN PERSON
WHERE X.owns[FRAGMENT]length > 1000
AND X.owns[FRAGMENT]length < 10000
;
is equivalent to
SELECT _1
FROM X IN PERSON, _1 IN X.name,
_2 IN X.owns[FRAGMENT]length, _3 IN X.owns[FRAGMENT]length
WHERE _2 > 1000
AND _3 < 10000
;
That is, the query returns the names of those people who own a fragment
with length greater than 1,000 and a fragment with length less than 10,000,
not those people who own a fragment with length between 1,000 and
10,000.
To express the later query we would need to use an explicit variable:
SELECT X.name
FROM X IN PERSON, Y IN X.owns[FRAGMENT]length
WHERE Y > 1000
AND Y < 10000
;